No.32 JOI国のお散歩事情 (Walking in JOI Kingdom)


時間制限:$2.0sec$ / メモリ制限:$256MB$

問題文

JOI 国には東西に走る 1 本の十分に長い道路がある.JOI 国の王宮が道路沿いにあり,JOI 国における道路沿いの位置は整数 A で表される.A = 0 のときは王宮の位置を表す.A > 0 のときは,王宮から東へ A メートル進んだ位置を表す.A < 0 のときは,王宮から西へ -A メートル進んだ位置を表す.

JOI 国の道路沿いには N 軒の家があり,家には西から順に 1 から N までの番号が付けられている.JOI 国には N 人の国民がいて,国民には 1 から N までの番号が付けられている.家 i には国民 i が住んでいる.家 i の位置は 0 でない偶数 Ai で表される.A1, ..., AN は全て異なる.

JOI 国では,近年国民の運動不足が問題になっている.国民の健康が気になった JOI 国の王様は,国民全員に散歩をする命令を出した.王様が命令を出すと,全ての国民は一斉に東向きまたは西向きに歩き始める.それぞれの国民がどちらの向きに歩き始めるかは,国民ごとに決まっている.全ての国民は,歩くときは 1 秒あたり 1 メートルの速度で歩く.

JOI 国の国民は皆おしゃべりが大好きである.散歩の途中にほかの国民に出会うと,その場所で立ち止まって世間話を始めてしまう.すでに立ち止まっている国民に出会った場合も同様である.一度立ち止まった国民は,再び歩き出すことはない.

JOI 国には Q 人の重要人物がいる.JOI 国の王様は,命令が出されてから T 秒後の,Q 人の重要人物の位置を把握しておきたい.命令が出されてから T 秒後の,Q 人の重要人物の位置を求めるプログラムを作成せよ.

入力

入力は,1 + N + Q 行からなる.

1 行目には,3 つの整数 N,T,Q (1 ≦ N ≦ 100000 (= $10^5$), $0 ≦ T ≦ 10^{18}$, 1 ≦ Q ≦ 1000,1 ≦ Q ≦ N) が空白を区切りとして書かれている.これは,JOI 国に家が N 軒あり,王様が命令を出してから T 秒後の,Q 人の重要人物の位置を把握しておきたいことを表す.

続く N 行のうち i 行目には,2 つの整数 Ai, Di ($-10^{18} ≦ Ai ≦ 10^{18}$, Ai は 0 でない偶数, 1 ≦ Di ≦ 2) が空白を区切りとして書かれている.Ai は家 i の位置を表す偶数である.すべての i (1 ≦ i ≦ N - 1) について,Ai < Ai+1 を満たす.Di は命令が出された後に国民 i が歩き始める方向を表す.Di = 1 のときは国民 i は東向きに歩き始める.Di = 2 のときは国民 i は西向きに歩き始める.

続く Q 行のうち i 行目には,整数 Xi (1 ≦ Xi ≦ N) が書かれている.これは,i 番目の重要人物が家 Xi に住んでいることを表す.すべての i (1 ≦ i ≦ Q - 1) について,Xi < Xi+1 を満たす.

与えられる 5 つの入力データのうち,入力 1 では N ≦ 100,T ≦ 10000を満たす.また,入力 2 では N ≦ 5000 を満たす.また,入力 3 では,ある整数 M (1 ≦ M ≦ N - 1) があって,すべての i (1 ≦ i ≦ M) について Di = 1,すべての j (M + 1 ≦ j ≦ N) について Dj = 2 を満たす.また,入力 1,2,3 では,入力に与えられる整数の絶対値は 1000000000 (= $10^9$) を超えない.入力 4,5 では,与えられる整数が 32 ビット符号付き整数の範囲に収まらないことに注意せよ.

出力

出力は Q 行からなる.

i 行目 (1 ≦ i ≦ Q) には,王様が命令を出してから T 秒後の,i 番目の重要人物の位置を表す整数を出力せよ.この値が整数であることは,問題文の条件より保証されている.

入出力例

入力1

5 5 3
-8 1
-4 2
-2 2
4 2
10 1
1
3
5

出力1

-6
-6
15

入力2

7 18 5
-100 1
-56 2
-34 1
-30 1
-22 1
-4 2
18 2
1
3
4
5
7

出力2

-82
-16
-13
-13
0





解説


単純な解法として,1 秒ごとに国民をすべて動かして愚直にシミュレーションをするというのが挙げられる. この解法の時間計算量は O(NT) であり,入力 1 に対しては時間内に正答を得ることができる. また,入力 2 においても時間をかければ正答を得ることは可能であろう. しかし,それ以降の入力で時間内に正答を得るのは難しいだろう.

十分に長い時間が経過したとき,各国民がどのような行動をとっているかを考えてみよう. その国民が東に向かって歩き始め,かつ自分より東に西に向かって歩き始めた国民がいない場合,その国民は東向きに歩き続けている. また逆に西に向かって歩き始め,かつ自分より西に東に向かって歩き始めた国民がいない場合にも,その国民は西向きに永遠に歩き続ける.

そのどちらでもない場合,その国民の向かう方向に,その国民と向い合わせに歩いてくる国民が存在する.すなわち,いつかはその国民は世間話をする. いま見ている国民(以下国民 A とする)が東向きに歩いているとする.西向きの場合も同様なので,ここでは割愛する. 国民 A から東の方向に一番近いところにいる西向きに動き出した国民を国民 B ,B のひとつ西にいる国民をCとおくと,A は B と C が世間話を始めた座標に到達したところで,世間話を始める.

つまり,東向きに進む国民のすぐ東に西向きに進む国民がいるところが見つかったら,十分な時刻が経過した後には, そこから国民の列を西に見ていったときのそこから連続する東向きに進む国民と,同じく国民の列を東に見ていったときのそこから連続する西向きに進む国民はすべて,その 2 人が出会う場所で世間話をしている.

以上のアイデアをコードに起こすと以下のようになる.

国民の列を西から順に見ていく.東向きに進む国民のすぐ東に西向きに進む国民が見つかったら,その 2 人の座標の平均をtとして, そこから西向きの国民または列の先頭が現れるまで西向きに列を見ていき,見た国民すべてに対し t という値を覚えておく. また,そこから東向きの国民または列の末尾が現れるまで東向きに列を見ていき,見た国民すべてに対し t という値を覚えておく.

最後に,時刻 T において,その国民が覚えている座標までその国民が到達しているかどうかを判定し, 到達しているなら先ほど覚えておいた世間話をする位置を,いないなら単にその国民の進む向きに距離 T 進んだ位置を出力すればよい.

実装においては,十分西に東向きに進む国民を,また十分東に西向きに進む国民を置いておく工夫をすることで,場合分けが減り,よりバグを生みにくいコードが書けるであろう.

この解法の時間計算量は O(N) となり,満点が期待できる.入出力が 32 ビット符号付き整数の範囲には収まらないことに注意せよ.