×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
CodeForces #162 Div1-E RodeSideTrees writer: snuke
Slide 2
Slide 2 text
֓ཁ 東西の道にそって木を植えたり切ったりするクエリ を処理し、各クエリ後に西→東方向のLISを求める 木は各クエリ前に1m ずつ伸びる 植える木の高さは10m 以下 切り倒す木は西から10本目以内 木の本数 N ≦ 10^5, クエリ数 M ≦ 2*10^5
Slide 3
Slide 3 text
۪ͳղ๏ 毎回 LIS を求める。 O(M N log N)となり、さすがに間に合わない。
Slide 4
Slide 4 text
ఆղ まず、木の成長を無視するために、 t 個目のクエリの時に植えられる木の高さを h から h-t に変換しておきます。 んで、木の(場所,高さ)を x-y平面上にぷろっとしてみる。
Slide 5
Slide 5 text
ఆղ ߴ͞ ॴ こんな感じ? すると・・・
Slide 6
Slide 6 text
ఆղ 常に右上方向に辿る最長経路がLISになってる! この場合、LISは赤いやつになります。 LISの普通の条件「hi < hi+1 」と暗黙の条件「xi < xi+1 」からくる特性 ߴ͞ ॴ
Slide 7
Slide 7 text
ఆղ さて、この問題におけるクエリは 下から10番目以内に木を追加 左から10番目以内の木を削除 と言い換えられます。 ߴ͞ ॴ
Slide 8
Slide 8 text
ఆղ とりあえず、各木に Longest Decreasing Subsequence の長さを記録することにしてみます。 図の木のところに LDS の長さを書き込んでみる。 木iの右上の領域中の最大値 + 1 が 木iのところに書き込まれるシステムらしい。 ߴ͞ ॴ 1 1 1 2 2 3 4
Slide 9
Slide 9 text
ఆղ 各クエリを爆速で処理する方法を考えてみよう。 ある木の LDS には右上の領域にある木のみが影響を及ぼし、 左 or 下 にある木は影響を及ぼさないことを利用しよう。 ߴ͞ ॴ 1 1 1 2 2 3 4
Slide 10
Slide 10 text
ఆղ 植えるクエリ (下から10番目以内に木を追加) 植える木よりも低い木をいったん抜いて、 順番に植え直す。 ߴ͞ ॴ 1 1 1 2 2 3 4
Slide 11
Slide 11 text
ఆղ 切るクエリ (左から10番目以内の木を削除) 切る木よりも左の木をいったん抜いて、 切る木以外を順番に植え直す。 ߴ͞ ॴ 1 1 1 2 2 3 4
Slide 12
Slide 12 text
ఆղ さて、ここで必要になるデータ構造はなんでしょう? 2次元segtree? → 更新にO(log^2 N)かかり、しかも定数項重そうな ので多分TLEします。 ߴ͞ ॴ 1 1 1 2 2 3 4
Slide 13
Slide 13 text
ఆղ 植えるクエリの時には x 方向の1次元segtree 切るクエリの時には y 方向の1次元segtree だけしか必要ない! O(log N)しかも定数項軽め! ※ただし、ノードの更新は両方のsegtreeに適応しないといけません。 ߴ͞(y) ॴ (x) 1 1 1 2 2 3 4
Slide 14
Slide 14 text
O(N * 10 * log N) くらい ܭࢉྔ
Slide 15
Slide 15 text
作問するにあたってLISとちょっと 仲良くなれた気がする。 ご清聴(?)ありがとうございました! CF#162へのご参加ありがとうございました! ·ͱΊ ←twitter(@the_nikaidoes)ͷΞΠίϯ