#P17446. 去心邻域 / Punctured Neighborhood

    ID: 19959 远端评测题 2000ms 256MiB 尝试: 0 已通过: 0 显示难度普及+/提高− 上传者: 标签>交互题Special Judge构造2026Ad-hoc高校校赛

去心邻域 / Punctured Neighborhood

题目描述

这是一道交互题。

有一个未知序列 BB,元素是 00 或 11,下标从 11 开始。你可以进行多次询问,每次询问指定中心 mm 以及半径 rr,交互器将返回 BB 的下标去心邻域 [m−r,m+r]∖{m}[m-r,m+r]\setminus\{m\} 内 11 的个数。尝试确定 BB 中一共有多少个 11。

注意,你询问的区间不能超出序列本身的边界。

交互方式

本题有多组测试数据。

首先读入一行,仅包含一个正整数,表示数据组数 T(1≤T≤1000)T (1\le T\le 1000)。

对于每组数据:

  • 首先读入一行,仅包含一个整数 nn (4≤n≤10004\le n\le 1000),表示 BB 的长度。
  • 发起询问时,需要以 ? m r 的格式输出一行并清空缓冲区,要求 2≤m≤n−1,r≥1,m−r≥1,m+r≤n2\le m\le n-1,r\ge 1,m-r\ge 1,m+r\le n。然后读入一行,包含一个非负整数,表示 ∑i=1r(Bm−i+Bm+i)\sum_{i=1}^r(B_{m-i}+B_{m+i}) 的值。
  • 当你确定答案后,以 ! x 的格式输出一行并清空缓冲区,其中 xx 表示 BB 中 11 的个数。
  • 特别地,若无论如何询问都不可能确定答案,输出一行 ! -1 并清空缓冲区。

每组数据的询问次数不能超过 3535。

任何不符合交互要求的输出,包括交互格式错误、超出交互次数限制等,都会导致未定义的运行结果。

2
4

1

1

5

4

2


? 2 1

? 3 1

! 2

? 3 2

? 2 1

! 5

提示

样例展示了一个可能的交互过程,两组数据中的未知序列分别为 1100 和 11111。

如何清空缓冲区:

  • 在 C 和 C++ 中,使用 fflush(stdout)(如果使用 printf)或 cout.flush()(如果使用 cout);
  • 在 Python 中,使用 stdout.flush();
  • 特别地,在 C++ 中,使用 cout << endl 会自动清空缓冲区。