AGC052 - B Tree Edges XOR

AGC050-Bを解いた

問題

重み付きの木(辺iが結んでいるのは頂点u_iv_i、重みはw _ {i} ^ {1})が与えられる。どれか一つ辺を選んでその辺と頂点を一つ共有するすべての辺について重みを選んだ辺の重みとの排他的論理和に置き換える。目標の重み(w _ {i} ^ {2})を達成するのは可能か?

解法

辺に対する操作は扱いにくいので各頂点に数(A_i、最初は全部0)が書いてあるとしてみて、辺の重みをA _ {u _ i} \oplus A _ {v _ i} \oplus w _ i ^ 1として表す。すると、辺iに対する操作は「A _ {u _ i}A _ {v _ i}をswapし、それぞれをw _ i ^1との排他的論理和に置き換える」と言い換えられる。ここで最終的にすべての i ( 1 \leq i \leq N)についてA _ {u _ i} \oplus A _ {v _ i} = w _ i ^2を満たす必要があり、Aの総xorが常に0であることと併せて考えれば最終的なA (A'と置く)は一意に定まる(ここでNが奇数であることが役立つ)。
さて、f(u,v)= 入力で与えられた木についての u,v間の辺の重みの総xorと定める。ここで、もともと頂点P _ iにあった値が頂点iに移ったことを考えるとこの値はf(i,P _ i)であり、これをA' _ iに一致させる必要がある。また、f(u,v)=f(1,u) \oplus f(1,v)より、
数列 (f(1,1),f(1,2) ... f(1,N))
数列(f(1,1) \oplus A' _ 1,f(1,2) \oplus A' _ 2 ... f(1,N) \oplus A' _ N)の並べ替えであるかどうかを判定すればよい。

考察

辺は扱いにくいので頂点でうまくできないか考える->変化を見る
不変量を見つける

提出コード

https://atcoder.jp/contests/agc052/submissions/48531932

AGC050 - C Block Game

AGC050-Cを解いた。

問題

無限に続く一列のマス目上で次のゲームを行う。文字列Sがあって、S _ i = S の時、Snuke君が1マス隣の空きマスに動くか、何もせずとどまる。S _ i = B の時、あなたは任意のマスを一つ選び通行不可にする。Snukeの両脇が通行不可である状態になったらあなたの勝ち、そうでなければSnuke君の勝ち。Sの一部が ? に置き換わってしまっている文字列が与えられる。考えられる元のSの内、あなたが勝てるものは何通り? mod998で求める。

解法

あなたの最適戦略は、明らかにSnuke君のいるマスの隣を通行不可にしてSnuke君から見てすぐ右の通行不可マスとすぐ左の通行不可マスの距離の差(これをLとする、L1になったらあなたの勝ち)を最小化すること。Snuke君の最適戦略はなるべく動ける範囲の真ん中付近にいること。
あなたのターンで、ここまでA個の S がこれまで連続してきた状態を考える。するとL
   L → min(A+1,\lceil \frac{L}{2} \rceil)
という変化をすることがわかる。切り上げは扱い辛過ぎるので切り捨てに直すことを考えて式を整理し、L' = L-1を考えると、
 L' → min(A,\lfloor \frac{L'}{2} \rfloor)
という変化をしているので、L'の最上位bitが下から何桁目かだけの情報を持てばよく、DPができる。

考察

切り上げは切り捨てに直そう

提出コード

https://atcoder.jp/contests/agc050/submissions/48503906
(がんばってO(N log N)に抑えた、もうちょっとスマートに書けないかしら...)

ARC115 - D Odd Degree

ARC115-Dを解いた

問題

無向グラフが与えられて、いくつか辺を削除できるとき奇点の数が K(0 \leq K \leq N)となるものの通り数 mod998を求める。

解法

連結成分ごとに独立に考えられる。グラフの全域木Tを取って、Tに含まれない辺を消すかどうか適当に選んだ後にTに含まれる辺を消すかどうか考えると、消し方と最終的な次数 mod2の状態は一対一なので、2^{m-n+1}*\left(\begin{matrix} n \\ k  \end{matrix}  \right)通りである。あとは畳み込みを使って計算。

考察

全体が連結でさえあれば好きなように状態を設定できることに気付けば普通に解けそう?

提出コード

https://atcoder.jp/contests/arc115/submissions/48165786

ARC111 - D Orientation

ARC111を解いた

問題

頂点iから到達できる頂点がC _ i個になるように、無向グラフの各辺に向きを付ける。解が存在する入力のみ与えられる。

解法

各辺(a_i , b_i)について、C _ {a _ i} \neq C _ {b _ i}であるものは向きが明らかで、そうでないものは閉路に用いられている辺となる。解が必ず存在することより、dfsで貪欲に向きを付けていけばよいことがわかる。

考察

わりとすんなりいけた。

提出コード

https://atcoder.jp/contests/arc111/submissions/me

ARC128 - D Neq Neq

ARC128-Dを解いた

問題

数列Aが与えられる。A _ i \neq A _ {i-1} ∧ A _ i \neq A _ {i+1}を満たすA _ iを削除する操作を好きなだけ行う。最終的なAの数mod998244353を求める。

解法

まず、2つ以上同じ数が連続している部分について考える。ここに含まれる数は絶対に削除できない。
以後2つ以上連続している部分を併合してしまって考える(つまり A _ i \neq A _ {i+1}(1 \leq i \lt N))。x _ 1 ... x _ kのindexを選ぶことが可能か考える(xは昇順)。まず、2以上の部分を併合したものが全てxに含まれるのが必要。そうすれば、全ての間の数を削除できれば良い。
x _ 1x _ 2の間の数を全て削除することが可能かどうかの問題を考える。間の数が1個までなら必ず実現可能。そうでなければ、間の数が3種類以上である、つまり間の数にA _ {x _ 1} \neq m ∧ A _ {x _ 2} \neq mを満たすmが存在するのが必要十分。これは帰納法で簡単に示せる。
DP _ i = (A _ iを最後に選んだ時の通り数)というDPを考える。累積和などを用いて更新していけば解が求まる。

考察

最初に選ぶものを固定するのはよくある、間の数を削除するのもどうしたら選べるかどうか考えれば容易に思いつく気がする。後半部分については間のA _ {x _ 1}A _ {x _ 2}が厄介なことに気付けばおのずと発想できると思う。

提出コード

https://atcoder.jp/contests/arc128/submissions/47802454
(セグ木を使っています、カス)

ARC168 - D Maximize Update

ARC168-Dを解いた

問題

N個の白いマス目とM個の操作が与えられる。i個目の操作では、L _ i \leq x \leq R _ iを満たすxマス目を黒く塗る。ここで、操作前よりも操作後のほうが黒いマスが多くないといけない。最大操作回数は?

解法

DP _ {l ,r} =区間[l,r]だけ考えた時の最大操作回数
としてDPする。DP _ {l , m-1}DP _ {m+1 , r}を合わせてDP _ {l,r}を更新することを考えると、新しく操作できるようになるのは高々1回だけ(mを黒にかえる)で、この操作il \leq L _ i \leq m \leq R _ i \leq rを満たす必要がある。これは、事前に区間[l,r]に完全に含まれる操作の数を累積和で計算しておけばよい。

考察

愚直なDP(マス目を使った/使ってないをbitで持つやつ)をまず考えてみてそこから区間を黒くすることに注目して区間だけの情報でDPすることを考えたかった。

提出コード

https://atcoder.jp/contests/arc168/submissions/47783642

ARC136 - C Circular Addition

ARC136-Cを解いた

問題

円環状で要素がすべて0の数列の連続部分列に1を加算する操作を何回か行う。所望の数列Aに一致させる最小操作回数は何回?

解法

Aから減算を繰り返して数列の要素をすべて0にすることを考える。
M=max(A) D _ i := A _ {i+1} - A _ i (A _ {N}A_0として) 、S := \frac{ sum(D) }{2}と置く。減算する区間の端に注目すると、まずDから二項選び、1の加算と1の減算をしてDの要素を全て0にする必要がある。この操作は明らかにS回は必要。そして、実験をすればAM-S以上の数に統一できることがわかる(MSの大小関係で場合分けすれば証明できるはず)。ここから全体に1を減算することを繰り返す。よって解はS + max(M-S,0) = max(S,M)

考察

区間に対する操作で端に注目するのは典型。厳密な証明できるようになりたい。

提出コード

https://atcoder.jp/contests/arc136/submissions/47751692