ABC466 C - Count Close Pairs

近い点のペア

考え方

まず、問題で言及されていないが、座標は当然整数とは限らないことに注意したい。

さて、インタラクティブ問題ということで身構えそうになるが、実はそこまで特殊なことはない。
普通に長さ $N$ の数列を渡されたと思って、そこから同様の問題を解くにはどうするか。
どうせ vector の中身は「これとこれの差 $1$ 以下?」しか見ない。
その確認が、vector の生データの引き算を if 文にかけるか、ジャッジに訊くかが変わっただけである。

とはいえ、今回の問題ではもう $1$ つ影響する点がある。
普通に長さ $N$ の数列を渡された場合、vector の中身の確認は、計算量が許す限り好きなだけ行える。
しかし、今回は $2N$ 回に制限されている。
確認がそれ以内に収まらなければならず、$O(N \log N)$ 回問い合わせて二分探索で解く方法は使えない。

ということで、これが $O(N)$ で済む尺取法を用いればよい。
vector の中身を $1$ 回確認するたびに $2$ つのインデックスの片方が必ず $1$ 進む。
つまり、両方のインデックスが最大 $N$ 回ずつ進む間の確認回数は $2N$ 回以下である。

インタラクティブ問題は、動作テストが難しい。
一度、普通の vector でテストをしながら尺取法を書き、最後に問い合わせ部分を書き換えるとよい。

具体例での動作

$N=5$ で、点 $1$ から点 $5$ までの座標が次のようになっている場合を考える。
これらの座標自体は、プログラムには入力されない。

点1: 0
点2: 0.4
点3: 0.8
点4: 1.5
点5: 3

最初は左端を点 $1$ とする。
右端を点 $1$ から順に動かすと、次のようになる。

右端 問い合わせ 最終的な左端 加える個数 合計
$1$ なし $1$ $0$ $0$
$2$ ? 1 2 → Yes $1$ $1$ $1$
$3$ ? 1 3 → Yes $1$ $2$ $3$
$4$ ? 1 4 → No、? 2 4 → No、? 3 4 → Yes $3$ $1$ $4$
$5$ ? 3 5 → No、? 4 5 → No $5$ $0$ $4$

右端が点 $5$ のときは、左端も点 $5$ まで進む。
同じ点同士については問い合わせず、条件を満たすものとして扱う。

実際に行った問い合わせは $7$ 回であり、上限の $2N=10$ 回以下である。
したがって、最後に ! 4 と出力する。

注意点

うっかり、"? 3 3" のような質問を投げないこと。
これは不正な質問である。
尺取法でこのような質問が生まれる場面は存在するので、問い合わせを投げずに "Yes" と判断する。

問い合わせを出力するたびに、標準出力を flush する必要がある。
出力後の改行に endl を用いることで改行ついでに flush される。

別解

特になし。