#D0969. 区间求和

区间求和

题目描述

Tom 写下了一个长度为 nn 的数组 a1,a2,…,ana_1, a_2, \dots, a_n,每个数都是正整数,但 33DAI 看不到数组里的内容。

33DAI 可以问 Tom:任选两个下标 l<rl < r,Tom 会告诉他 al+al+1+⋯+ara_l + a_{l+1} + \dots + a_r 的值。注意每次询问的区间至少要包含 22 个数,也就是不允许直接问某一个位置上的数。

问完之后,33DAI 必须报出数组中最小的是哪个数,以及它第一次出现的位置。请你帮他在允许的次数内完成这件事。

交互规则

本题没有输入文件,你通过与交互器对话来获取信息。你的程序需要从标准输入读入数据、向标准输出写数据。

第一步:从标准输入读入一行两个整数 n,qn, q(3≤n≤10003 \le n \le 1000,1≤q≤1061 \le q \le 10^6),其中 nn 是数组长度,qq 是你最多可以询问的次数。

接下来的每一次操作,你向标准输出写一行,格式必须是下面两种之一:

  • 1 l r:询问 al+al+1+⋯+ara_l + a_{l+1} + \dots + a_r。要求 1≤l<r≤n1 \le l < r \le n(区间长度至少为 22)。交互器会回答一行,内容是这个和。
  • 2 v p:报告答案。其中 1≤v≤1061 \le v \le 10^6,1≤p≤n1 \le p \le n。
    • 如果 vv 确实等于数组中的最小值,且 pp 是这个最小值第一次出现的位置,交互器会输出一行 win,本题该测试点通过;
    • 否则本题该测试点判为 Wrong Answer。

报告答案的那一次操作不计入询问次数。

每次输出一行后,必须立即刷新输出缓冲区,否则交互器会读到旧数据而判错。C++ 中的做法是:

printf("1 %d %d\n", l, r);
fflush(stdout);
// 用 cout 的话写 cout << "1 " << l << " " << r << endl;(endl 会刷新)或 cout.flush();

限制:询问次数不能超过 qq 次,否则判为 Wrong Answer。

样例 1

下面是一次合法的交互过程(n=4n = 4,q=10q = 10,隐藏的数组是 a=[5,3,8,3]a = [5, 3, 8, 3])。空行只是为了排版,实际输出中不要有空行。

交互器        你的程序
4 10
              1 1 2
8
              1 1 3
16
              1 2 4
14
              2 3 2
win

样例解释

  • 交互器给出 n=4n = 4、最多问 1010 次;
  • 你问 1 1 2,交互器回答 8,即 a1+a2=8a_1 + a_2 = 8;
  • 你问 1 1 3,交互器回答 16,即 a1+a2+a3=16a_1 + a_2 + a_3 = 16;
  • 你问 1 2 4,交互器回答 14,即 a2+a3+a4=14a_2 + a_3 + a_4 = 14;
  • 你报告 2 3 2:数组里最小的是 33,它第一次出现在第 22 个位置,交互器回答 win,本测试点通过。

样例 2

见 sumq1.in 与 sumq1.ans。

其中 .in 就是本次交互开始时交互器给出的 nn 与 qq;.ans 是本测试点隐藏的数组 aa,供你本地调试时查看,实际评测时你并看不到它。

样例 3

见 sumq2.in 与 sumq2.ans。

其中 .in 就是本次交互开始时交互器给出的 nn 与 qq;.ans 是本测试点隐藏的数组 aa,供你本地调试时查看,实际评测时你并看不到它。

数据范围

对于所有测试数据,保证:

  • 3≤n≤10003 \le n \le 1000;
  • 1≤ai≤1061 \le a_i \le 10^6;
  • q≥nq \ge n。
子任务 分值 n≤n \le qq
11 3030 1010 25002500
22 100100
33 4040 10001000