【AtCoder】ABC 466 C - Count Close Pairs

C - Count Close Pairsatcoder.jp favicon

実行時間制限: 2 sec / メモリ制限: 1024 MiB / Difficulty: 658 / NoviSteps: 2Q / 配点: 300 点

問題概要

数直線上に、点 11, 22, \ldots, NN が 左から右に並んでいる。

最初、あなたには整数 NN のみが与えられる。

その後、あなたはジャッジに以下の質問を 2N2N 回まで行うことができる。

  • ? i j: 1i<jN1 \leq i < j \leq N を満たす整数 i,ji,j を選び、点 ii と点 jj の距離が 11 以下であるか質問する。

距離が 11 以下である場合は Yes、そうでない場合は No として、質問の答えがジャッジから標準入力に返される。

距離が 11 以下の 22 点組の個数 XX を以下の形式で出力せよ。

  • ! X

制約

  • 2N1032 \leq N \leq 10^3

考察

ABCでは見慣れないインタラクティブ問題。

数直線上での点 ii の座標を xix_i とする。

ii に対して、自身よりも右側にあって、距離が 11 以下のもので最大の番号の点を rir_i とする:

ri=max{j1i<jN,xjxi1}r_i = \max\{j \mid 1 \leq i < j \leq N, x_j - x_i \leq 1\}

このとき、点 ii と組にできる点の個数は、i+1,i+2,,rii+1, i+2, \ldots, r_iriir_i - i 個であるから、答えは

i=1N(rii)\sum_{i=1}^{N} (r_i - i)

となる。


ここで重要なのが、rir_i は単調増加するということである。

なぜなら、組 (i,ri)(i, r_i) の距離が 11 以下であるなら、組 (i+1,ri)(i+1, r_i) の距離も 11 以下であり、

xrixi+1<xrixi1x_{r_i} - x_{i+1} < x_{r_i} - x_i \leq 1

が成り立つからである。


したがって、 i=1,2,,Ni = 1, 2, \ldots, N に対して、尺取り法の要領で rir_i を単調増加に求めることができる。

? i j という質問の答えについて、

  • Yes: rijr_i \geq j であることがわかるので、rir_i を右に動かすことができる。
  • No: ri<jr_i < j であることがわかるので、今の ii の探索を終了して ii を右に動かすことができる。

という動きをすれば、質問回数は最大でも 2(N1)2(N-1) 回で済む。

実装例

CPP
1.#include <bits/stdc++.h>
2.using namespace std;
3.
4.#define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++)
5.
6.template <typename T>
7.inline bool chmax(T& a, T b) { return ((a < b) ? (a = b, true) : (false)); }
8.
9.// ======================================== //
10.
11.bool query(int i, int j) {
12. cout << "? " << i << " " << j << endl;
13. cout << flush;
14.
15. string res;
16. cin >> res;
17.
18. return res == "Yes";
19.}
20.
21.int main()
22.{
23. int N;
24. cin >> N;
25.
26. int ans = 0;
27. int right = 1;
28. rep(left, 1, N + 1) {
29. chmax(right, left);
30.
31. while (right + 1 <= N) {
32. if (query(left, right + 1)) {
33. right++;
34. }
35. else {
36. break;
37. }
38. }
39.
40. ans += right - left;
41. }
42.
43. cout << "! " << ans << endl;
44. cout << flush;
45.
46. return 0;
47.}
atcoder.jp favicon

実装時間: 10分

コメント

かなり久々のインタラクティブ問題でぎょっとしたが、尺取り法そのままで解くことができ一安心。