atcoder regular contest 036 解説
TRANSCRIPT
A-数式で表す
● t[i] = i日目の高橋くんの睡眠予定時間● 3 ≦ i ≦ N なる i のなかで
t[i-2] + t[i-1] + t[i] < K
となる最小の i を、存在するなら求めよ
A-解法
● t[i] = i日目の高橋くんの睡眠予定時間● 3 ≦ i ≦ N なる i のなかで
t[i-2] + t[i-1] + t[i] < K
となる最小の i を、存在するなら求めよ● N ≦ 100,000なので、iを全通り試しても十分
まにあう– 満点解法
A-注意点
● i = 1, i = 2のときは調べないようにしなければならない– t[-1]に参照して実行時エラーになりうる
● 不等号に注意– t[i-2] + t[i-1] + t[i] ≦ K にすると失敗する
– 問題文をよく読みましょう
概要
•長さ 𝑁の数列があります。
• ℎ𝑠 ≦ ℎ𝑠+1 ≦ ⋯ ≦ ℎ𝑡 ≧ ⋯ ≧ ℎ𝑢 となる整数組 (𝑠, 𝑡, 𝑢)のうち、 𝑢 −𝑠 + 1の最大値を求めてください。
• 1 ≦ 𝑁≦ 300,000
• 1 ≦ ℎ𝑖≦ 1,000,000,000
部分点解法
• すべての整数組 (𝑠, 𝑡, 𝑢)について考えます。
•整数組 (𝑠, 𝑡, 𝑢)が実際に山の条件を満たしているかは、O(𝑁) 回の判定でできます。
•考えられる整数組は O(𝑁3) 個あるので、全体で O(𝑁4) の計算量となります。
考察
• 𝑠や 𝑢に関して、外側に伸ばせるのに伸ばさないのはもったいないです。
•先に 𝑡を固定して、 𝑠 と 𝑢 を外側に伸ばせるだけ伸ばすという方針で O(𝑁2) に減らすことができます。
• O(𝑁2) よりも高速にするために、さきほどの 𝑡に関して考えてみます。
満点解法
•先ほどの 𝑡 としては、データの両端であるか、ℎ𝑡−1 ≦ ℎ𝑡 かつ ℎ𝑡 ≧ℎ𝑡+1であるような 𝑡だけ考慮すれば良いことが分かります (そうでない場合、 𝑡 − 1あるいは 𝑡 + 1の方がより良い結果になることが分かります)。
• このように限定した場合、どの要素も高々定数回しかアクセスされないので、全体で O(𝑁) となります。
概要
•長さ 𝑁の 0,1 からなる数列があります。
• ? となっている場所をうまく 0,1 で埋めて、どのように部分列を取ってきても 0,1 の個数の差が 𝐾以下となるようにします。
•考えられる総数を 1,000,000,007 で割った余りを求めてください。
• 1 ≦ 𝑁≦ 300
• 1 ≦ 𝐾≦ 𝑁
部分点解法 1
• すべての 0,1 割り当てを考えます。
• すべての配置が定まれば、その配置が条件を満たしているかはO(𝑁3) で判定できます。
•考えられる個数は 2𝑁個あるので、全体で O(2𝑁𝑁3) となります。
• 1 つめのデータセットに対して正解できます。
部分点解法 2
•動的計画法を用いて左から順に調べることを考えます。
•考えるべき状態数としては、今まで調べた場所と、調べた場所の右端から左に伸ばしたときに (0 の個数)-(1 の個数) として何が考えられ、何が考えられないのかという情報です。
•後者 (0,1 の差) は、(0 の個数)-(1 の個数)として、 <1 が考えられる>、<2が考えられる>、…、 < 𝐾が考えられる>、 <-1 が考えられる>、 <-2 が考えられる>、…、 < −𝐾が考えられる> という、合計で 2𝐾 ビットの情報を持っていれば表現できます (差 0 は、長さ 0 の列を考えれば常に存在します)。
部分点解法 2
• dp[i][j] = (場所 iまで調べていて矛盾 (差が 𝐾 を上回る状態) がなく、かつ場所 iから左に伸ばしたときに考えられる差がビット列 j となるような 0,1 割り当ての総数) とします。
•状態遷移は、今見ている場所に 0,1 のどちらが入るかを決めれば次は一意に定まるので各状態につき O(1) で判定できます。
• このような動的計画法は O(2𝐾𝑁) で実行できます。
• 𝐾が小さいデータセット 2 に関して正解することができます。
考察
• すべての状態を考えていても、指数オーダーの計算量となります。
• (0 の個数)-(1 の個数) の最大値および最小値が一致するもの同士をまとめて数え上げたいです。
•実は最大値および最小値が一致するものをまとめても、特に問題はありません (なぜなら、差が 𝐾 を最初に越えるのは、必ず最大値か最小値のいずれかであり、かつ状態遷移によってどの状態が考えられるかは、平行移動 (+ 差が 0) という変化しかないので、最大値と最小値だけ考慮しておけばよいことになります)。
満点解法
• dp[i][j][k] = (場所 iまで考えて矛盾 (差が 𝐾 を上回る状態) がなく、iから左に伸ばしたときの (0 の個数)-(1 の個数)の最大値が j で最小値が –k であるようなものの総数) とします。
• このような動的計画法は O(𝑁3) で実行できます。
• このアルゴリズムなら満点を得ることができます。
D-問題概要
● 辺の無いグラフ(頂点数N)がある。● 以下の2種類のクエリQ個に答えよ
– 頂点x, yの間にdメートルの辺を引く
– 頂点xから頂点yへのwalkのなかで偶数メートルのものがあるか判定せよ
※walkというのは同じ辺を複数回通ることを許した経路のこと。
D-考察3
● 二部グラフの性質– 片方の集合に属す頂点から、もう片方の集合に属す
頂点に移動するwalkは必ず辺の数が奇数
– 赤から始めるとかならず
赤、青、赤、青・・・
というwalkになるから
D-考察3
● 二部グラフでないグラフの性質– どの2点間も辺の数が偶数のwalkがある
なぜ?
– 無理やり2つの集合に分けることを考える
– どこかで赤 → 赤もしくは青 → 青の辺ができる
– その辺を経由すれば偶奇を自由に調整できる
D-部分点1
● N,Q ≦ 3,000● クエリ毎に毎回質問された頂点が二部グラフか
どうか判定しても充分間に合う● 二部グラフ判定法
– 適当な頂点を赤く塗る
– そこから始めて、隣接する頂点の色が異なるようにDFSしながら塗っていく
– 隣接する頂点の色がおなじになる辺があったら二部グラフではない。なかったら二部グラフ
D-部分点1
● 二部グラフ判定法– 判定と同時に塗り分けもできる
● まとめ– 頂点X、頂点Yが連結でない NO
– 連結で二部グラフでない YES
– 連結で二部グラフで同じ色である YES
– 連結で二部グラフで違う色である NO
● 30点獲得
D-満点解法1
● パターン1, 2の辺については適当に処理する– 変更する情報は定数個なので、あまり計算量に影響
しない
● パターン3の塗り直しをどうするか– 頂点数が少ない方を塗り直すようにすれば良い
– いわゆる「マージテク」
– どの頂点も塗り直されるタイミングで自分が属する連結成分の大きさが2倍以上になる
● たかだかlogN回しか塗り直さない
D-満点解法1
● 注意– DFSの計算量はO(頂点数)ではなくてO(辺の数)
– それならば頂点数ではなくて辺の数の大小でマージテクをするべきでは?
● 結論から言うと問題ない● 先と同様の論法で各辺がDFSで走査される回数も
O(logN)程度
– 二部グラフかどうかわかっているので、全域木の辺のみを管理するという手もある
D-満点解法まとめ
● 満点解法1– マージテクを使っていちいち色を塗り直す
– O(Q log N)
● 満点解法2– 縮約によって塗り直す色を定数個に減らす
– O(Q α(N)) ※α(N)はアッカーマン関数の逆関数
D-満点解法3
● もっとシンプルな解法がある● 各頂点について
– 赤く塗ったもの
– 青く塗ったもの
をあらかじめ用意しておく
● 結ぶ辺の長さが偶数なら同じ色どうしを結ぶ● 結ぶ辺の長さが奇数なら違う色どうしを結ぶ