競技プログラミング用 知識集積所

ABC430C - Truck Driver

最終更新:

sport_programming

- view
管理者のみ編集可


問題


必要知識

B以下レベルの内容は省略

考え方

まず愚直解を考えてみる。
範囲からLとRの値を選び、その中のaとbをカウントすることで、O(N^3)で求めることはできる。
これの高速化としてまず思いつくのは累積和でaとbをカウントを高速に行うことだが、それでもO(N^2)にしかならず、必要な速度には届かない。
根本的に、「範囲からLとRの値を選び」の時点でO(N^2)は確定なので、その時点で無理である。

そこで、Rの値を固定したときに条件を満たすLの値が何個あるかを高速に求められないかと考えてみる。
(Lを固定してもいいが、ここではRを固定する方で説明をする)
Rを固定してある状態だと、Lの範囲は「遡ってaがA個以上、bがB個未満ある場所」の個数である。
aの個数やbの個数は範囲を広げると単調に増加するため、この範囲はひとつながりになっている。
よって、何らかの方法でこの区間の左端と右端を高速に求められれば、個数はその位置の差でよいことになる。

これは尺取法のwhileで回す方の足を2つ持たせ、右端をRとする区間で「aがA個以上」「bがB個以上」になるLの範囲を求めるものとしてそれぞれを利用すればよい。
あるいは、計算量にlogNがついてしまうが、二分探索※でもこの問題なら間に合うと思われる。

解答例


注意点

long long型を使用する

Aが1でBが非常に大きいと、N(N-1)/2通りのほぼ全てが該当し、int型から溢れる。
long long型を使用すること。

別解

ウィキ募集バナー