ABC lessons learned2 - zettsu-t/zettsu-t.github.io GitHub Wiki

AtCoder Beginner Contest lessons learned (ABC 151-200)

ABC 6,8問䜓制(126..最新)のD問題をだいたい解いたので、そこから埗た教蚓をたずめおいきたす。

トップペヌゞぞ

ABC 151-160

ABC 151-D

コヌドはこちら

マスを頂点をみなしお、あるマスから他のマスぞの最短距離を求める。126-Dず同様にBFSで求たる。朚ではないので、既知の最短距離ではないマスは移動しない(移動するず無限ルヌプになる)。

ABC 151-E

コヌドはこちら

組み合わせ総数ず环積和を䞊手く貯える。

$A_1 ... A_n$ から $k$ 個遞ぶ方法ずしお

  • 䞡端を遞んで残り $k-2$ 個遞ぶ
  • 先頭(1番目)ず最埌の前(n-1番目)を遞んで最埌(n番目)は遞ばない。他を $k-2$ 個遞ぶ。
  • 先頭(1番目)ず最埌の前の前(n-2番目)を遞んでそれ以埌は遞ばない。他を $k-2$ 個遞ぶ。

... ずいう方法を考える。芁するに最初ず最埌の芁玠の添え字の差(幅-1)が $n-1, n-2, ... , k-1$ になるように遞ぶ。それぞれの遞び方は ${n-2} \choose {k-2}$ 通りで、最初ず最埌の芁玠の添え字の差ず定数 $k$ で決たる。ここで ${{n-1} \choose {k}} = {n \choose {k}} * (n-k) / n \quad for \quad n>0$ を䜿うこずで、遞び方の数を逐次的に求めるこずができる。

最初ず最埌の芁玠の添え字の差が $w-1$ ず決たっおいるずき、 $f(X)$ は $(a_w-a_1) + (a_{w+1}-a_2) + ... + (a_{n}-a_{n-w+1})$ であり、笊号をたずめるず $(a_w + a_{w+1} + ... + a_{n}) - (a_1 + ... + a_{n-w+1})$ である。たずめお足す郚分ずたずめお匕く郚分に぀いおは、环積和を䜿うこずでそれぞれ $O(1)$ で求たる。

よっお添え字の幅が $O(N)$ なので党䜓の蚈算量も $O(N)$ になる。

ABC 151-F

コヌドはこちら

二点を通る最小の円たたは䞉点を通る最小の円のうち、どちらか小さい方である。ある円の䞭心ず半埄を決めたずきに、他の頂点が収たっおいるかどうかは総圓たりで分かる。

二点を通る最小の円に぀いおは、䞭点を円の䞭心にすればよい。座暙をあらかじめ2倍し、距離の二乗で比范するず、蚈算誀差が無くなる。

䞉点を通る最小の円に぀いおは、倖接円の䞭心を公匏で求める。分母が0のずきを特別扱いする。䞭心の座暙は敎数にならないので、䞭心から他の座暙の距離を比范するずきは蚱容誀差を持たせる。

ABC 152-D

コヌドはこちら

Nが200000ず読んで、いろいろ探玢するより数え䞊げた方が早く実装できる、ず勘づく。

先頭ず末尟の組は9x9=81通りしかないので、 $1..N$ を81通りに分類すればよい。K進数の最䞊䜍の桁は、Kで繰り返し割っおK未満になったずきの数である。

ABC 152-E

コヌドはこちら

手抜きも時に重芁。

$A_{1..N}$ の最小公倍数(LCM)を求めお、LCM/AをBにすればいい。 std::lcm() を䜿うずオヌバヌフロヌするので、 $A_{1..N}$ を玠因数分解しお埗られるそれぞれの玠数の出珟回数を求める。䞀床でも出珟する玠数に぀いお最倧出珟回数を环乗し、それらを掛けたものをLCMにする。

ここで $B_i$ を真面目に求めようずしお、LCMを構成する玠数の個数から $A_i$ を構成する玠数の個数を匕いお残った玠数を党郚かけるずTLEする。単に $LCM / A_i = B_i$ で問題ない。

ABC 153-D

コヌドはこちら

䞊手く状態遷移をたずめれば、状態数が指数になるのを防げる。

モンスタヌをどういう順番で攻撃しおも、䜓力が0になるたでの䜓力の枛り方は同じ、ずいうこずが重芁である。よっお䜓力の枛り方の経路は䞀通りだけ(2で繰り返し割る)で、ある䜓力のモンスタヌが䜕䜓あるかだけ数えれば攻撃回数になる。

ABC 153-E

コヌドはこちら

Greedyだず思ったらDPだった。

ずいうこずでDPで解く。このずき、 $i$ 番目たでの魔法を䜿い(ずいうか $i$ 番目の魔法を初めお繰り返し䜿うこずにしお)、 $h$ のダメヌゞを䞎えた時( $h$ 以䞊は䞀埋 $h$ )ずする、 $dp[i+1][j+A]$ に配るのは $dp[i+1][j] + B$ である。 $j$ を内ルヌプに眮くず魔法を無制限に䜿えるこずを衚珟できる。品物を䞀個だけ加えるナップザックDPの $dp[i][j] + B$ から匕くず䞊手くいかない。

ABC 153-F

コヌドはこちら

遅延評䟡いもす法

解き方は耇数あるが、遅延評䟡いもす法が分かりやすい。モンスタヌの座暙 $1..N$ におけるダメヌゞをいもす法で曎新しおいく。巊にいるモンスタヌから最小回数で順に倒すgreedyずいうこずは分かったが、回数がバむナリ1/0でないこずをすっかり忘れおいた。

ABC 154-D

コヌドはこちら

期埅倀の加法性を䜿う。

隣接するK個のサむコロずあるので、サむコロK個の期埅倀は、サむコロを1個加えおK+1個になったら、最埌に加えたサむコロの期埅倀を枛らす。期埅倀の加法性からこれが成り立぀。移動平均の求め方ず䞀緒である。

ABC 154-E

コヌドはこちら

桁を䞊から芋るか、䞋から芋るか。

䞋の桁から芋るのが正解である。もしかしたら䞊の桁から芋おも解けるのかもしれないが、私には解けなかった。公匏解説を芋るず再垰で解けるず解るが、もう少し読み解くず以䞋のようになる。数字列 $abcd...$ があり、非0の数字が $abcd$ に $k$ 個芁るずき、

  • $k=0$ なら $a=b=c=d=0$ の1通り
  • $k<4$ ぀たり $k$ が $abcd$ より短すぎるなら0通り

を特別扱いする。次に䞋の桁 $...$ ぞの繰り䞋がり $inCarry$ が起きるかどうかを匕数で受け取っおおく。最䞋䜍桁に぀いおは $inCarry=0$ である。

  • $d=0$ か぀ $inCarry=1$ なら、䞋の桁 $...$ ぞの繰り䞋がりがあり、か぀䞊の桁 $c$ からの繰り䞋がりが必ず起きる( $outCarry=1$ )。それ以倖で、䞊の桁からの繰り䞋がりが起きるかどうかは状況次第である( $outCarry=0$ )。
  • $inCarry=1$ なら $d$ を1匕く。぀たり $d:=(d+9) mod 10$ にする。

ここで $d$ の倀に぀いお考察し、䞊の桁ぞの再垰を考える。

  • $d$ があるこの桁は0ずいうこずにしお、 $k$ を消費しない。この組み合わせの数は、末尟を削陀した数字の䞊び、繰り䞋がり、非0の数字の数がそれぞれ $(abc, outCarry, k)$ の堎合に぀いお求めたものである(なので再垰的定矩である)。
  • $d>0$ ならこの桁は非0の倀 $1..d$ のいずれかにしお、 $k$ を1消費する。この組み合わせの数は、同様に $(abc, outCarry, k-1)$ の堎合に぀いお求めたものを $d$ 倍した倀である。
  • $d<9$ ならこの桁は非0の倀 $d+1..9$ のいずれかにしお、 $k$ を1消費する。この組み合わせの数は、同様に $(abc, 1, k-1)$ の堎合に぀いお求めたものを $9-d$ 倍した倀である。䞊の桁から繰り䞋がりがないず、 $d$ より倧きな数字をこの桁に蚭定できない。

再垰呌び出しで匕数で䜕床も呌び出すこずに備えおメモ化するずよい。再垰ずメモ化するためのキヌは、 $N$ の桁を衚珟する数字の郚分列そのものではなく、文字列の先頭からの長さでよい。再垰呌び出しは $N$ の最䞋䜍桁から順に取り陀くからである。぀たり再垰呌び出しの匕数ずメモ化のキヌを(入力 $N$ から䞊䜍䜕桁取るか、繰り䞋がり、非0の数字の数)にする。

ABC 154-F

コヌドはこちら

勘で解いた。

向きを盎亀座暙系(列はXが増える方向に右、行はYが増える方向に䞊)ずする。矩圢領域 $(r1,c1)-(r2,c2)$ に入る盎前にたどり着くたで䜕通り数え、矩圢領域に入り(これは䞀通り)、矩圢領域内を移動する方法を数える。

矩圢領域 $(r1,c1)-(r2,c2)$ に䞋から入るずき、 $(r1-1,x) : c1 \leq x \leq c2$ にたどり着いお、 $(r1,x)$ で矩圢領域に入る。これは ${r1-1+x} \choose {x}$ 通りである。

$(r1,x)$ から矩圢領域内を移動する方法を数える。矩圢領域の高さ $h = r2 - r1 + 1$ ずする。矩圢領域に初めお入っおから $i = 0..(c2-c1+1)$ 列ちょうど移動する方法が䜕通りか $C[i]$ を数える。 $i = 0$ なら $h$ 通りである。未蚌明だが $C[i+1] = C[i] (h+1) / (i+1)$ が成り立぀。

环積和 $\sum_{j=0}^i C[i]$ を取るず、矩圢領域に初めお入っおから $i$ 列以内移動する方法が䜕通りか分かる。ここに矩圢領域に入るたで䜕通りか掛ける。これらの和が答えである。巊から入る方法も同様に求める。

$1..2 \times 10^6$ の階乗ず、 $1..2 \times 10^6$ 逆数をあらかじめ求めお蚈算を高速化する。

実は二次元环積和で解けるらしいが、どうやっお高速化するのかわからない。

ABC 155-D

コヌドはこちら

困ったら二分探玢。

二数を曞けた結果が、正、れロ、負の䞉通りに分けお、 $k$ を超える積が䜕個あるか尺取り法で数え䞊げる。緻密な実装が問われる。

ABC 155-E

コヌドはこちら

154-Eず䌌おいる。

基本的には154-Eず同様なのだが、入力が倧きいのでDFSは䜿えず、BFSするずTLEした。なので単玔にメモ化しながらルヌプする。メモ化するのは、(䞋から䜕桁目たでに、䞋の桁から繰䞊りがあったかどうか) のずき䜿う玙幣の最小枚数 $DP[0..N][0..1]$ である。

154-Eの繰り䞋がりず同様に、ある桁 $d$ 、䞋の桁から繰䞊りがあったかどうか $inCarry=0 or 1$ があったずき、䞊の桁から繰り䞋げるかどうか $outCarry=0 or 1$ を固定しお、

  • $d:=d+inCarry$ に぀いお
  • $d<10$ ならその堎で $d$ 枚玙幣を払い
  • $d>0$ なら䞊の桁から借りおお釣りをもらうこずにしお $10-d$ 枚玙幣を払う

最䞊䜍桁が繰り䞊がったずきを考慮する必芁がある(そうしないず91の答えが3でなく2になっおしたう)。このためには、 $min(DP[N][inCarry]) += inCarry$ ずすればよい。答えは $min(DP[N][0..1])$ である。

ABC 156-D

コヌドはこちら

二項定理に察する基本的な知識が問われる。それずダブリングの䜿いどころである。

Nから0..N通り遞ぶ組み合わせの総和は $2^N-1$ 通りである。なぜなら $1..N$ 番目の芁玠を遞ぶか遞ばないかを、党芁玠に぀いお独立に数え䞊げるこずず同じだからである。1匕くのは䜕も遞ばないケヌスを陀くためだ。

nが $10^9$ ず倧きいので $2^n$ を繰り返し求めるず終わらない。 $2^{i+j} = 2^i * 2^j$ なので $i$ ず $j$ を2のべき乗に぀いお求めるず巚倧なnでも $2^n : mod : 1000000007$ が求たる。 $2^{0..32} : mod : 1000000007$ はダブリングで求める。コヌドスニペットを曞いおテストしおおくずよいだろう。

ここたできたら $2^n - {}_n C_a - {}_n C_b$ が答えである。

ABC 156-E

コヌドはこちら

k個のお菓子をn人に分ける。

自力では解けず、こちらの解説を甚いた。この解説通り実装すればよい。

解説䞭、 $n-i$ 個の郚屋に1人以䞊、合蚈で $n$ 人を入れる組み合わせの総数は、 $n$ 人を $n-i$ 郚屋に䞀人ず぀入れお、残り $i$ 人を $n-i$ 郚屋に入れる組み合わせの数である。これは $i$ 人ず $n-i-1$ 個の仕切りに぀いお、人ず仕切りを区別しない順列組み合わせの数 ${{i+n-i-1} \choose {i}}$ = ${{n-1} \choose {i}}$ = ${{n-1} \choose {n-i-1}}$ である。

${n \choose {n-i}}$ = $n!/(i!*(n-i)!)$ = ${n \choose {n-(i-1)}} * (n-i+1) / i$ を甚いお組み合わせの総数を逐次的に求めないずTLEする。

ABC 157-D

コヌドはこちら

Union-find朚を知っおいるず解ける、知らないず解けないか実装が倧倉な問題である。

友達の友達は友達ずいう掚移関係は、友達関係をグラフで衚珟した時の連結成分である。なのでそれぞれの連結成分の頂点数から、既に友達である関係の数ず、 同じ連結成分で ブロックしおいる関係の数を匕く。異なる連結成分でブロックしおいる関係は、友達の友達は友達ずいう掚移関係は成り立たないので匕かない。

ABC 157-E

コヌドはこちら

力業すぎる。

type 2ク゚リからセグメント朚を連想する。文字は英小文字しかないのだから、26本のセグメント朚を䜜り、ある区間にa,b, ..., z があるかどうか曎新しお調べればよい。type 1 ク゚リで倉曎前の文字が䜕であったかは、 $S$ を盎接曎新すれば分かる。

ABC 158-D

コヌドはこちら

コレクションを反転するのはコストが高いが、反転したずみなすのフラグ1個曞き換えるだけである。手元の列に察しお、

  • 手元の列が反転しおいないずきに先頭に远加するのは、列の先頭に远加する
  • 手元の列が反転しおいないずきに末尟に远加するのは、列の末尟に远加する
  • 手元の列が反転しおいるずきに先頭に远加するのは、列の末尟に远加する
  • 手元の列が反転しおいるずきに末尟に远加するのは、列の先頭に远加する

反転しおいるか吊か、先頭ず末尟のどちらに远加するか if文で4通りに分けおもいいし、xorを取っお2通りにたずめおもよい。

ABC 159-D

コヌドはこちら

党郚の組み合わせの個数を挙げおから、ある皮の組み合わせの個数を匕く。

敎数 $x$ が曞かれたボヌルが $m$ 個あるなら、ボヌルの遞び方は $((m+1) * m) / 2$ 通りである。敎数 $x$ から個数 $m$ ぞの連想配列にしおおけば $x$ の倀域に぀いお悩たなくお枈む。

埌はボヌルが䞀個 ($A_1 .. A_N$) 枛ったら、その分ボヌルの遞び方が枛るのでその倀を蚈算する。

ABC 159-E

コヌドはこちら

制玄をよく芋る。

$H \leq 10$ から、鉄則本をA72を思い出す。暪方向(行方向)に沿っお切る方法は $2^{H-1}$ しかないので総圓たりできそうである。埌は瞊方向(列方向)の切り方をgreedyに求める。

䟋倖凊理ずしお、 $K$ が小さいずきはすべおの列を幅1で切っおも制玄を満たさない可胜性がある(䟋えば $K=1$ ですべおのマスが1のずき)。そのような暪方向の切り方は芋぀け次第陀倖する。埌は䞀列ず぀ $i=1..W$ 列の右偎で切れるかどうか詊しお、

  • 切れ端に含たれる 1が $K$ 個を超えたら、 $i$ 列の右偎ではなく巊偎で切る。 $i$ 列を起点に調べなおす。
  • そうでなければ切らずに、 $i+1$ 列の右偎で切れるかどうか調べる。

暪方向+瞊方向に切った回数の最小倀が答えである。

ABC 160-D

コヌドはこちら

入力サむズから蚈算量を芋切るこずが倧事である。

頂点の䜍眮を、Xより右、X-Y間、Yより巊に堎合分けしお解くずずおもめんどくさい。BFSで距離を求めるず簡単である。こういうずきは $N$ が二千しかないこずから、各頂点を出発点ずしお総圓たりでTLEしないず予想できる。

蟺の長さが固定のずきにBFSで距離を求める方法は既出なので省略する。

ABC 160-E

コヌドはこちら

std::vector::resize() を䜿う

問題文から X<A, Y<B なので堎合分けを枛らせる。無色のリンゎを補充しなければならない状況はなく、眮き換えるだけでよいこずが分かる。リンゎを色別に、矎味しさの降順に゜ヌトしお、赀いリンゎは元々 $X$ 個だったず考えるず楜である。 std::vector::resize() は䜙分な芁玠を切り捚おるので䟿利である。

眮き換えるなら最もおいしくない赀ず緑のリンゎを、最も矎味しいリンゎに眮き換えればよいだろう。これは尺取り法でできる。赀ず緑のリンゎをすべお眮き換え終わったらもうできるこずはない(もっず矎味しい無色のリンゎに眮き換えたはずだから)ので、尺取り法のむンデックスに気を付ける。

ABC 161-170

ABC 161-D

コヌドはこちら

これも 160-Dず同様に、入力サむズから蚈算量を芋切るこずが倧事である。

再垰ずメモ化で取りうる組み合わせを环蚈するずめんどくさそうである。しかし10進数5桁しかないのだから、䞊の桁に䞋の桁(0には0ず1、9には8ず9、それ以倖の $i$ は $i-1, i, i+1$ をくっ぀けおも党探玢できる。

ABC 161-F

コヌドはこちら

ゎヌルから芋た方が簡単である。

たず $N = i \times K+1$ を満たす数は $K$ ず぀枛算しお1になる。次に $N = K^{i}(K \times j+1)$ を満たす数は $K$ ず぀陀算しお1になる。よっお $i = 2.. \sqrt{N}$ を決め打ちしお、 $i$ で割れるだけ割っお残った数を $i$ で割った䜙りが1なら、 $i$ は $K$ の候補になる。私の実装はこのように $N$ から枛らしたが、解説にあるように1から $i$ を構成する方が考えやすい。

念のため $K$ の候補に $N-1$ の玄数ず $N$ を加えおから1を陀いた。 std::set で重耇を陀いおいる。

ABC 162-D

コヌドはこちら

これも 160-D, 161-Dず同様に、入力サむズから蚈算量を芋切るこずが倧事である。配列の添え字がはみ出さないように党探玢すればよい。

ABC 162-E

コヌドはこちら

玠因数分解か玄数列挙しお包陀原理だろうず思ったが、具䜓的な解法たで時間が掛かった。

前凊理ずしお、 $1..K$ それぞれの玄数を列挙する。これは玄数の偎を $i = 1..K$ に固定しお、 $i$ の倍数は玄数 $i$ を持぀ず蚈算する。

$A_1$ を $1..K$ に固定しお党探玢する。

敎数 $B$ の玄数を小さい順に $S_B = [1,...,B]$ ずする。 $A_1 = B$ のずきにある数 $D \in S_B$ があっお $GCD(A) = D$ ずなるのは、 $A_{2..N}$ がすべお $D$ の倍数であり、なおか぀ $GCD(A)$ が $D$ 以倖の $D$ の倍数にならないずきである。これを包陀原理で求める。

$S_B$ の降順に調べる。 $A_{2..N}$ がすべお $B$ の倍数になる組み合わせは、 $1..K$ にある $B$ の倍数の任意の組み合わせなので、 $(\lfloor K/B \rfloor)^{N-1}$ 通りである。これを $C_B[B]$ ずする。

$S_B$ に぀いお、 $D \in S_B , D \ne B$ に぀いお考える。 $A_{2..N}$ がすべお $D$ の倍数になる組み合わせは、 $(\lfloor K/D \rfloor)^{N-1}$ 通りである。ここから、 $GCD(A) = F &gt; D$ になる組み合わせを匕く。これは $F \in S, F mod D = 0$ なる $F$ に぀いお $C_B[E]$ 通りを匕く。

$S$ の降順に $C_B[]$ を求め、答えに $\sum_{i \in S} i C_B[i]$ を足す。

ABC 163-D

コヌドはこちら

巚倧な数 $10^{100}$ が意味するのは、数を䜕個足したかが和から区別できるこずである。この習慣を芚えおおく。

それさえわかれば、 $0..N$ から $K$ 個遞んだずきに、和ずしお衚珟できる数ずできない数を求めればよい。

  • 和の最小倀は䜕も遞ばない0、最倧倀は党郚遞ぶ $sum(i=0..{N})$ である。
  • $s = sum(i=0..{K-1})$ が最小倀なので、それより小さい数 $S$ 個は和になりえない。
  • 足す数をそれぞれ $N-i$ ずすれば巊右反転しお、 $sum(i=0..{N})$ たでの $S$ 個は和になりえない。
  • それ以倖の和は衚珟可胜である(和にする数の集合に察しお、ある数ずそれより1倚い数を亀換すればよい。このような数は必ずみ぀かる)

ABC 164-D

コヌドはこちら

  • 鉄則本の「8.6 文字列のハッシュ」問題 A56を知っおいるず解ける
  • 环積和から郚分列の総和を取る方法が䜿える

文字列から郚分文字列を取っおいくずきに、郚分文字列から埗られるハッシュのような情報を埗る。ある数が2019で割れるかどうかは、2019のすべおの玠因数(3ず673)で割れるかどうかず同じである。぀たり3で割った䜙りず673で割った䜙りを、文字列の末尟から先頭に向かっお取っおいく。説明の郜合䞊、文字列を std::reverse で逆順にしお最も䞋の桁を文字列の先頭ずする。

...abcdef ず桁がたくさんある敎数のうち、䞋䜍1,2,3...桁を673で割った䜙り(mod 673)に぀いお考える。3で割った䜙りも同様である。

  • f mod 673は、実際に割れば分かる
  • ef mod 673は、(e*10 + (f mod 673)) mod 673
  • def mod 673で割った䜙りは、(d*100 + (ef mod 673)) mod 673
  • cdef mod 673で割った䜙りは、(c*1000 + (def mod 673)) mod 673

こうしお最䞊䜍の桁たで、最も䞋の桁から連続する桁を673で割った䜙りを蚈算できる。10, 100, ... ず $10^n$ を673で割った䜙りも䜵せお蚈算しおおく。

次に䞋の桁から順に0に眮き換えおいく。

  • 最初は䜕も眮き換えない。このずきf, ef, def, ... を673で割り切れるかどうかは既に調べおある
  • 最䞋䜍の桁を0に眮き換える。䟋えばcdefをcde0に眮き換える。cde0が673で割り切れるかどうかは、 $(cdef - f) : mod : 637 \equiv 0$ ぀たり $f$ を673で割った䜙りず $cdef$ を673で割った䜙りが等しいずいうこずである。ここで f mod 7 を固定しお、f mod 7 ず等しい f, ef, def, ... を数えれば、題意の総数の䞀郚が求たる。
  • 䞀般的には、䞋の桁から連続する $i (\geq 0)$ 個の0を眮き換える。䞋i桁 mod 7 ず等しい f, ef, def, ... を数えれば、題意の総数が求たる。䞋i桁の倀は初期倀を0ずし、 $i$ を曎新するごずに $10^{i}$ * i桁目の数字 mod 673 を足す。
  • f, ef, def, ... mod 673 ず f, ef, def, ... mod 3 から、 f, ef, def, ... mod 2019 が求たる。これは $i$ ず関係ないので、mod 2019をキヌずしお該圓する䜙りの出珟回数を䞀床数えお連想配列に保存しおおく。

この考え方は、郚分列の総和を求めるのに环積和を䜿う方法ずよく䌌おいる。和を䜙りに眮き換えただけなので。

Mod 3ずmod 673はACLを䜿うず曞きやすい。

#include <atcoder/all>
using ModInt3 = atcoder::static_modint<3>;
using ModInt673 = atcoder::static_modint<673>;

ABC 165-C

コヌドはこちら

$N$ が小さいのでDFSの党探玢で行ける。

ABC 165-D

コヌドはこちら

盎芳的には、Aを増やすほどBで割った䜙りが溜たっおいっお、Bになるず䜙りが0に戻る、ずいうこずである。 $A &lt; B$ だず戻らないので入力条件に気を付ける。

ABC 165-E

コヌドはこちら

方針は立ったが実装に手間取った。

参加者を固定しお、察戊堎が動くず考える。同じ参加者ず二床察戊しないずいう条件を考えるずき、参加者が動くのも察戊堎が動くのも盞察的には同じである。

ある察戊堎の割り圓お $(L,R)$ ずする。 $(R - L) mod N$ および $(L - R) mod N$ ずなる察戊堎が䞀意なら題意を満たす。ここで呚回を考慮しお $mod$ は非負の最小な数ずする。

$N$ が奇数なら、 $M$ を偶数ずしお、 $M = 2,4,...,\lfloor N/2 \rfloor$ にする。 $-M$ に぀いおは $N-M mod N$ が奇数なのでやはり䞀意性がある。このような察戊堎は $L + R = N-1$ になる組を列挙すればできる。

$N$ が偶数なら、 $M = 1,3,...,\lceil M/2 \rceil$ な察戊堎、 $M = 2,4,...,M/2$ な察戊堎を䜜る。前者は $L + R = 1 + \lceil M/2 \rceil$ になる組を列挙すればできる。埌者は $L + R = 2 + M/2$ になる組を列挙し、 $\lceil M/2 \rceil$ 足しおずらす。

ABC 166-D

コヌドはこちら

䞉次以䞊の倚項匏の問題は、n条根を取るず倉数の取る領域がそれほど倧きくないので総圓たりできる。

$A^5-B^5 = (A-B)(A^4+A^3B+A^2B^2+AB^3+B^4)$ なので、 $X$ の玄数を求めお総圓たりすればいい。 $A-B$ は玄数を総圓たりし $A$ を決め打ちしお総圓たりすればいい。 $X^5-(X-1)^5 &gt; 5X^4$ なので、 $A$ は䞋限が0、䞊限は ${5*x}^{1/4}$ もあれば十分だろう。

玄数を求めるは頻出なのでコヌドスニペットを曞いおおく。平方数の玄数を二床数えおしたいがちである。

ABC 166-E

コヌドはこちら

絶察倀は順序を固定すれば倖せる。

組み合わせを列挙するので、䞀般性を倱わず $A_i, A_j$ (i<j) なペアだけ考えればよい。定匏化するず以䞋のように倧倉だが、手を動かすず䜕ずなくわかっおくる。

題意から $A_1 + A_2 = 1, A_1 + A_3 = 2, ...$ ず解る。これを $A_1, A_2, ...$ に぀いお数えあげるず $O(N^2)$ なのでTLEするが、 $A_1$ を $A_2$ に取り換える方法がありそうである。

実際できるのである。 $A_i + A_j = j-i \Leftrightarrow A_j - j = -(A_i + i)$ である。よっお $A_j - j : for : j=1..N$ が䜕個あるか求めお連想配列にいれおおき、 $-(A_i + i) : for : i..N$ がいく぀あるか連想配列で匕いお総和を求めるず答えが出る。

ABC 166-F

コヌドはこちら

文字 $x \in {A,B,C}$ に察応する倀を $V_x$ ずする。

$xy$ の操䜜で $x = 0, y = 0$ だず詰むので、詰みを回避する。ずもかく 00 にしなければよく、䞀手先読みをすればいい。盎近の操䜜を $xy$ , 次の操䜜を $pq$ ずする。

$xy$ ず $pq$ のうち䞀぀だけが䞀臎するずする。制玄から、少なくずも䞀぀は䞀臎し、二぀ずも䞀臎する堎合もある。代衚ずしお $x = p$ ずするが、他も同様である。 $V_x = 1 \land V_q = 0$ なら、今の操䜜で $V_x = 0$ にするず詰むので、 $V_x$ を1増やし、 $V_y$ を1枛らす。

それ以倖の状況では、 $V_x &lt; V_y$ なら $V_x$ を1増やし、 $V_y$ を1枛らす。そうでなければ $V_x$ を1枛らし、 $V_y$ を1増やす。

こうしおすべおの操䜜を決めた埌に再生しお、 $V$ が負になったら No 、ならなければ操䜜を出力する。

䞍倉量だず思ったらやはり䞍倉量だった。和が 1,2,3以䞊で区別できた。䞀手先読みであるのは䞊蚘ず同じ考察である。

ABC 167-E

コヌドはこちら

動的蚈画法できなさそう、ずいう芋切りが必芁。

同じ色が䞊んでいるブロックが残り $0 \leq i \leq K$ 組ずいうのはメモ化できなさそうである。そこで発想を倉える。 $N$ 個のブロックがあり、同じ色が䞊んでいるブロックが $i$ 組あるなら ${N-1} \choose {i}$ 箇所ある。

これをすべおの $i$ に぀いお求める。同じ色が䞊んでいるブロックがなければ、色は $M*(M-1)^{N-1}$ 通りある。同じ色が䞊んでいるブロックが $i$ 組あるならブロックを圧瞮する、぀たり $N-i$ 個のブロックがあるず考えお、同じ色が䞊んでいるブロックが ${N-1-i} \choose {i}$ 箇所ある。156-Eず同様、組み合わせの数は逐次的に求める。

ABC 168-D

コヌドはこちら

郚屋1から他の郚屋の距離をBFSで求める。方法は既出の通り。

ABC 168-E

コヌドはこちら

2時間近くかかったが、久しぶりに青diffを解けた。

$A_i \cdot A_j + B_i \cdot B_j = 0$ が内積だずいうこずはすぐわかる。 $(A_i, B_i) = (0,0)$ ならどんな $(A_j, B_j)$ ずの内積も0になるので原点を特別扱いするこずも分かる。しかしそこからが長考だった。

自明な答えずしお、むワシは䞀匹なら答えは1である。

原点なむワシ $(A_i, B_i) = (0,0)$ をいったん無芖しお、 $(A_i, B_i) \ne (0,0)$ なるベクトルを既玄のベクトルにしお、ある向きのベクトルが䜕皮類あるか数えられるようにする。これは $(A_i, B_i)$ を $gcd(|A_i|, |B_i|)$ で割る。割ったものに察しお、以䞋の通り数えお連想配列 std::map<std::pair<Num, Num>, Num> に収める。ここで0皮類増やす、぀たり連想配列の゚ントリだけ䜜っおおくず埌の凊理が楜である。

  • 既玄なベクトル $(A_i, B_i)$ を1皮類増やす
  • 察称なベクトル $(-A_i, -B_i)$ を0皮類増やす
  • 盎亀するベクトル $(-B_i, A_i)$ $(B_i, -A_i)$ を0皮類増やす

次に登堎したベクトル $(A_i, B_i)$ を皮類ごずに std::vector<std::pair<Num, Num>> に远加する。ここで $(A_i, B_i)$ が出珟したら $(-A_i, -B_i), (-B_i, A_i), (B_i, -A_i)$ も既に出珟したこずにするず、察称たたは盎亀するベクトルをたずめお䞀回だけ远加できる。远加したかどうかは std::set<std::pair<Num, Num>> で管理する。

ベクトル $(A_i, B_i)$ の皮類ごずに、むワシをどう組み合わせられるか考える。 $(A_i, B_i)$ および $(-A_i, -B_i)$ から $P_i (\geq 0)$ 匹、盎亀する $(-B_i, A_i)$ および $(B_i, -A_i)$ から $Q_i (\geq 0)$ 匹遞べるずする。盎亀するむワシは遞べないが盎亀しないむワシは遞べるので、遞べる組み合わせは $C_i = 2^{P_i} + 2^{Q_i} - 1$ 通りである。

ベクトル $(A_i, B_i)$ の皮類が異なるむワシは盎亀しないので、独立に組み合わせられる。よっお遞べる組み合わせは $\prod_i C_i : (A_i, B_i) \ne (0,0)$ である。

ここで重芁なこずずしお、原点なむワシ $(A_i, B_i) = (0,0)$ が $K$ 匹いたら、それぞれ䞀匹ず぀クヌラヌボックスに入れるこずができる。これを忘れるずWAする。よっお答えは $\prod_i C_i : (A_i, B_i) \ne (0,0) + K$ である。

1260 ms掛かっおいるのを芋るず、ベクトルの皮類を数え䞊げるにはもう少し掗緎された方法がありそうだ。

ABC 169-D

コヌドはこちら

玠因数分解しお、玠数pで1回、2回、3回... 割っおみる。玠因数ずその数をコヌドスニペットを曞いおおく。

ABC 169-E

コヌドはこちら

二分探玢ではなかった。

$lower..upper$ の範囲の䞭倮倀はいかようにも䜜れる。では $lower$ ず $upper$ を二分探玢で求めるコヌドを曞くず異垞にややこしい。実は $lower$ は $A$ の䞭倮倀、 $upper$ は $B$ の䞭倮倀である。プログラミングずいうより数孊の問題である。

小数が出るず厄介なので、入力倀を二倍しお答える前に半分にする。 $lower$ が奇数なら取りうる䞭倮倀は1個倚い( $upper$ も同様)。

ABC 170-D

コヌドはこちら

任意の組み合わせを数え䞊げるのに、゜ヌトしおも䞀般性を倱わないだろうか。

小さな数でそれより倧きな数を割るこずはできない。よっお昇順に゜ヌトしお、自分より倧きな数で割り切れるかどうか確かめる。そのたた実装するず $O(N^2)$ になっおしたうので、玄数が既に出珟したかどうか調べる。

なお同じ倀の数が耇数ある堎合は互いに割り切れるので、答えの回数には含めない。

ABC 170-E

コヌドはこちら

力業すぎる。

C++の速床でゎリ抌すなら、幌皚園をキヌ、園児のレヌトを倀ずする std::map<Num, std::multiset<Num>> を䜜ればよい。min(党幌皚園のmaxレヌト)は、党幌皚園を茉せたセグメント朚で管理する。関数を std::max , 元(モノむド)を inf にしおおけば、2秒を切っおACできる。1-based indexで通すなら入力を読み蟌むずきもそうする。

ABC 171-180

ABC 171-D

コヌドはこちら

芁玠が䜕個あるかは気にしない。

なので $B_i$ が䜕個あるかを連想配列で管理する。ク゚リごずに、 $B_i$ がn個あるなら、 $C_i$ をn個远加しお $B_i$ をn個削陀する。

ABC 171-E

コヌドはこちら

E問題が10分以䞋で解けるこずもある。

めったにないE問題茶diffである。XORパリティず蚀えばわかる。自分以倖の数字のXORを取るずいうこずは、数字の各桁に぀いお、自分以倖の数字で1が出た回数が奇数回なら1、偶数回なら0を意味する。

$a_{1..N}$ を XORしおパリティを求める。1 XOR 1 = 0から、数字の各桁に぀いおある $a_{1..N}$ は1回だけ数えるのず同じである(Nは偶数なので)。぀たり数字の各桁に぀いお、 $a_{1..N}$ での出珟回数が奇数回なら1、偶数回なら0を意味する。

ずいうこずで数字の各桁に぀いお、 $a_{1..N}$ での出珟回数が奇数回(1)で、 $a_1=a_{2..N}$ での出珟回数が奇数回(1)なら、 $a_1=0$ である。同様によく考えるず、求める答えはパリティず $a_i$ のXORである。

ABC 172-C

コヌドはこちら

Aをから䜕冊読むか決めたら、Bから最倧䜕冊読むかは䞀意に決たるので、尺取り法で求たる。

ABC 172-D

コヌドはこちら

瞊の物を暪にする。

ある数に玄数が䜕個あるかを調べるのは倧倉である。しかし $1..N$ に玄数 $i$ が䜕個あるかは、 $\lfloor N/i \rfloor$ 個ずすぐわかる。瞊暪を入れ替えるだけですんなり解ける(私自身はこの解法を思い぀かなかったが)。

ABC 173-D

コヌドはこちら

あれこれ悩むより、手を動かしお詊した方が早い。

最埌の䞀人は誰かにずっお心地よさは䞎えないので、フレンドリヌさが最倧の人から降順到着するのがよいず分かる。どこに入れるかであるが、Nが十分倧きいずき、フレンドリヌさが䞊䜍二名の間に入れればそこの心地よさが最小になる。぀たり N, N-1, N-1, N-2, N-2, ... ずなる。

ABC 173-E

コヌドはこちら

方針はすぐ立ったが詰めが芁る、最近のARCらしい問題である。

絶察の倧きい方から $K$ 個取る。この集合を $S$ ずし、残りを $U$ ずする。

$S$ の積が非負ならそのたた答えである。そうでなければ $S$ の芁玠を䞀぀ $U$ の芁玠䞀぀ず取り換えお積を非負にするこずを考える。

  • $S$ の正の数で最も絶察倀が倧きいものを(もしあれば) $P_s$ ずする
  • $S$ の負の数で最も絶察倀が倧きいものを(もしあれば) $N_s$ ずする
  • $U$ の正の数で最も絶察倀が倧きいものを(もしあれば) $P_u$ ずする
  • $U$ の負の数で最も絶察倀が倧きいものを(もしあれば) $N_u$ ずする
  1. $P_s, N_s, P_U, N_u$ がすべおあるなら、 $P_u / N_s &gt; N_u / P_s$ なら $P_u, N_s$ を亀換する。そうでなければ $N_u, P_s$ を亀換する。亀換埌の $S$ の積が答えである。
  2. $(P_s, N_s)$ たたは $(P_U, N_u)$ の組の䞀方だけあるなら、その組の倀を亀換する。亀換埌の $S$ の積が答えである。
  3. それ以倖なら絶察倀の小さい方から $A$ を $K$ 個遞んで掛けたものが答えである。特に $A$ に0があるなら答えは0である。

分数を比范するずきは、互いの分母を掛けお敎数にしお比范する。

ABC 174-C

コヌドはこちら

$K$ が小さいので、実際に求めれば分かる。

ABC 174-D

コヌドはこちら

遞択肢が二぀あるが、片方があればもう片方は芁らないずいうこずがある。

RWの䞊びはよいがWRの䞊びはよくないので、WRを枛らせばいい。ならばRだけ巊にずらっず䞊べお、Wだけ右にずらっず䞊ぶよう、Wを右に寄せればいいず分かる。぀たり最巊のWず最右のR入れ替えればよく、この回数を求める。これは尺取り法でできるので O(N)で解ける。

石を入れ替えれば灜いは1たたは2枛るするかもしれないが、石の色を倉えおも1しか枛らないので、石の色を倉える意味はない。

ABC 174-E

コヌドはこちら

二分探玢である。

䞞倪の最倧長を決め打ち、 $K$ 回以内で切れるか枬ればよい。長さ $L$ の䞞倪を $i$ 回切るなら明らかに $i$ 等分が最適なので(䜕を思ったか $2^i$ 回切っお数十分䜿っおしたった)、䜕回切る必芁があるかは $\lceil L/i \rceil$ 回である。

なのだが、探玢幅の䞋限を $1e-6$ にしないず、WAかTLEになる。敎数挔算だけで解こうしたが䞊手くいかなかった。だがやはり敎数で解かないず解が安定しないらしい。敎数解法はこちらで、区間のleftではなくright぀たり total > k ではない最小の倀を返す。二分探玢はこれが垞にややこしい。

ABC 174-F

コヌドはこちら だが、実質的にはある蚘事 そのものである。

Mo's Algorithm で解く。Mo's Algorithmを知らないずどうにもならない。

ABC 175-D

コヌドはこちら

解の方針は立぀が、実装が非垞に蟛い。

たず状態遷移をルヌプ成分に分解する。DFSでもよさそうだが、union-find朚の代衚元を䜿うず簡単である。それぞれのルヌプ成分ごずにスコアを求めお、その最倧倀が答えである。

問題はスコアの求め方である。䞀呚するずスコアが正の倀になるなら、できるだけたくさん呚回する。そうでそうでなければ䞀呚しなければよい。䞀呚に満たない堎合のスコアは起点を終点の組を総圓たりしお $O(N^2)$ で求たる。

ず曞くず簡単に芋えるが、WAしないように実装するのがものすごく倧倉である。二呚分のスコアの环積和を求めお、すべおの起点ず長さを総圓たりすればいいはずなのだが、それだけではどうしおもWAを取り切れない。

ABC 175-E

コヌドはこちら

䞉次元DP

䞉次元の動的蚈画法を䜜る。行、列、ある行でのアむテム取埗回数 0..3 を䞊から䞋、巊から右にスキャンする。0行0列は䟡倀0のアむテムがあるずみなす、぀たり入力アむテムの䜍眮を1-base indexingするず、スタヌト地点のアむテムを拟うかどうかを䟋倖凊理しなくお枈む。

巊から右にスキャンしおアむテムを拟うずアむテムの数が1増えるが、行を䞋に移ったずきに拟ったアむテムの数が0に戻るこずに泚意する。

ABC 176-D

コヌドはこちら

普通にBFSで解ける。

ず、公匏解説に曞いおある。おそらくその方が実装が簡単なのだろう。私の解き方は少し回りくどいが以䞋の通りである。

  • すべおのマスを、ワヌプなしで行ける範囲で連結成分分解する。Union-find朚を䜿うずできる。
  • 連結成分を頂点、ワヌプで行ける連結成分を蟺ずするグラフを構成する。頂点番号は連結成分の代衚元( $x+y*1000$ でいい)、ワヌプで行けるかどうかは各頂点から25通り詊せばよい。同䞀連結成分同士を蟺で぀ながないように泚意する。
  • このグラフに぀いお、出発点の連結成分から目的地の連結成分たでに経由する、最短距離぀たり最小の蟺の数をBFSで求める。到達䞍可胜なら距離は無限倧である。

倚重蟺を䜜らないようグラフは std::map<Num, std::set<Num>> にするが、頂点から延びる蟺は edges[current] で取り出す。 edges.at(current) だず、蟺がないずきに䟋倖が飛んでプロセスが終了しおしたう。

ABC 176-E

コヌドはこちら

瞊暪を独立に考える。

砎壊察象が最も倚い行ず、砎壊察象が最も倚い列はそれぞれ独立に考えるこずができる。よっお砎壊察象が最倚の $rmax$ である行(耇数あり埗る)ず、砎壊察象が最倚の $cmax$ である列(耇数あり埗る)が候補になる。これらの行列の亀点ぎったりに砎壊察象があるず、砎壊察象が䞀぀枛るので、これら行列の組を党探玢する。

実は党探玢しおも倧䞈倫である。もし亀点に砎壊察象がないのであれば答えは $rmax+cmax$ ず解るのでその堎で終了できる。この探玢は最倧 $M+1$ 回なので十分早く探玢を打ち切るこずができる(公匏解説より)。

ABC 177-D

コヌドはこちら。

グルヌプ分けずいえばunion-find朚である。

友達の友達は友達ずいう掚移関係は連結成分に分解できる。これをバラバラにするには、連結成分の数だけグルヌプを䜜っお、疎な連結成分の人をそれぞれのグルヌプに集めればいい。よっお最小のグルヌプ数は最倧の連結成分の芁玠数である。これは気が付かなかった。

圓時は自前で実装したUnion-find朚を䜿っおいた。今はACLを䜿っおいる。

ABC 177-E

コヌドはこちら

甚語の定矩を萜ち着いお理解すれば分かる。

$GCD(A,B,C) = GCD(GCD(A,B),C) = GCD(A,GCD(B,C))$ なので、すべおの芁玠のGCDが1より倧きければ not coprime である。

Pairwise coprime なら必ず setwise coprime だが逆は成り立たないので、 pairwise coprime ではない䟋を䞀぀でもみ぀けたら setwise coprime ず出力し、そうでなければ pairwise coprime である。これは $A_{i+1}$ の玠因数が $A_1..A_i$ の玠因数を含むかどうかで分かる。

ABC 178-D

コヌドはこちら

DFS(幅優先探玢)はスタックの深さに泚意すればきれいに再垰で曞ける。

数列は順序が異なれば違うものず数えるので、3以䞊の数を $S$ から匕いお残りを再垰的に求めればよい。 $S$ は2000しかないので、メモ化しおおけば蚈算時間が指数オヌダヌになるのを防げるし、スタックもあふれない。

ABC 178-E

コヌドはこちら

45床回転。

$x+y$ で等高線が匕けるのは分かったが、 $x-y$ の等高線は䜿い道が分からなかった。匏倉圢は公匏解説にあり、より詳しい解説が蚘事にある。

しかし匏倉圢をしなくおも盎芳的に理解する方法がある。xが巊、yが䞊に増える座暙系で、x+y等高線は巊䞋-右䞊関係をずらえ、x-y等高線は右䞋-巊䞊関係を捉えるず思えば、二点のマンハッタン距離は、二点における等高線の差の倧きい方ず䞀臎する。

ABC 179-D

コヌドはこちら

貰うDPで解く。

配るDPでも解けるようだが、貰うDPで解いた。たず区間を $L$ の昇順に゜ヌトする。 $i=2..N$ のマスに぀いお、区間を順番に調べお

  • 区間の終わり $i - R &lt; 1$ ならおわり
  • そうでなければ区間 $\lbrack max(1, i-L), i-R \rbrack$ のマスに行く方法を党郚足す

区間にある貰うマスに行く方法を环積和で管理すれば、区間は10以䞋なので蚈算量は $O(N)$ になる。答えも环積和の差分で出力する。

なおこの問題は遅延評䟡セグメント朚でも解ける。実装は こちら 。ただしこの問題では $K$ が小さいので、DPで12 ms、遅延評䟡セグメント朚635 ms ずなり高速化には寄䞎しない。

ABC 179-E

コヌドはこちら

厳密解を求めるより、鳩の巣原理で解く。

䜙りは $0..M-1$ しかないのだから、同じ䜙りが二床出たら以埌は呚期的になる。よっお、呚期を求めお、

  • 呚期に入る前
  • 呚期を繰り返し
  • 呚期の途䞭で $n$ に達する

に぀いお和を求める。ただし呚期に入る前に $n$ に達するこずがある。

ABC 179-F

コヌドはこちら

遅延セグ朚で解ける。想定解法は遅延セグ朚ではないが、考え方は同じである。

行 $r$ における最巊にある癜い石の䜍眮を $P[1][r]$ ずする。初期倀は $N$ である。同様に列 $c$ における最䞊にある癜い石の䜍眮を $P[2][c]$ ずする。初期倀は $N$ である。

操䜜 $T, a$ に察しお、以䞋の通り考える。 $T = 1$ ず $T = 2$ の操䜜は互いに察象なので、 $T = 1$ だけ瀺す。 $T = 2$ は右や䞊を適宜読み替える。

操䜜 $T$ においお、癜い石ず挟む盞手は $R = P[T][a]$ にある。挟んだ石 $max(0, R - 1)$ は黒くなる。 $i=1..R$ に぀いお、最䞊の癜い石は $P[3-T][i] = min(P[3-T][i], a)$ になる。これはapply最小、prod最小のセグメント朚で曎新できる。

党おのク゚リに぀いお凊理するず癜い石が枛っお答えが求たる。

ABC 180-D

コヌドはこちら

ゞムに通うず匷さがどう倉わるかは今の匷さず今通うゞムだけで決たり、これたでどう鍛えたかには関係ない。これをマルコフ性ずいう。

なので䞡方のゞムに通ったずしお匷さが䜎くなる方を遞べばよい。匱いうちは匷さをA倍にし、その埌はB増やすずよさそうだが、そこたで考察しなくおも解ける。

ABC 180-E

コヌドはこちら

䞉角䞍等匏

䞉角䞍等匏を考えない䞀般的な巡回路に぀いおは、 ある郜垂を蚪れたかどうかが $2^N$ 通り、ある郜垂を蚪れたかどうか぀たり蚪れた郜垂の集合が決たっおいるずきに、 今いる郜垂から他の郜垂ぞの遷移が $N^2$ である。これを収束するたで繰り返すず $(N^3*2^N)$ になっおTLEする。

しかし䞉角䞍等匏が成り立぀ずきは同じ郜垂を二床蚪れる必芁はない。入力䟋2が匕っかけである。このずきは蚪れた郜垂の数が1,2,...,Nになるように集合を拡匵すればいい。぀たり(蚪れた郜垂の集合, 今いる郜垂)をキヌ、倀を最小コストずするDPを行い、すべおの郜垂を蚪れお今郜垂1にいるずきの倀を答えにする。

ABC 181-190

ABC 181-D

コヌドはこちら

算数的な方法で解ける。Nが倧きいので、順列を数え䞊げるずTLEする。

算数的な方法は、数字をいい感じに組み合わせるず、䞋から3桁目が偶数か奇数かず、䞋から1,2桁目の組を䜿っお8の倍数になるかどうか調べる。芁は000, 008, ..., 192 かどうか調べる。間違い無いがコヌド量が倧きい。

実は䞋䞉桁を求める方が簡単である。こちらの蚘事を参照。

ABC 181-E

コヌドはこちら

数孊的考察が必芁。

解を満たす組は、小さい倀から順に二぀ず぀取る、である。最も倧きい倀ず最も小さい倀を組む、ではない。この前提が間違っおいるずどうにもならない。これが分かれば环積和を぀かっお蚈算量を枛らせる。

ABC 182-D

コヌドはこちら

問題をよく読む必芁がある。問われおいるのは最倧瞬間座暙であっお、 $A_{1..i}$ 䞀組の動䜜完了埌ではない。

环積和を环積するのは頭がこんがらがるが、コヌドに萜ずし蟌めばそのたたである。 $i$ 組目の動䜜をするず、最倧瞬間座暙は以䞋の最倧倀である。

  • 出発点(右偎にしか行かない堎合)
  • $A_i$ だけ進たずに行ける堎所(これたでの最倧瞬間座暙)
  • $A_i$ 進むこずで初めお行ける最倧瞬間座暙

この埌、䜍眮に环積和ず $A_i$ を足し、环積和に $A_i$ を足し、环積した動きの最倧瞬間座暙が過去最倧なら差し替える。

ABC 182-E

コヌドはこちら

垰玍法。瞊暪を独立な問題ずしお考える。

瞊方向に光が届くかず、暪方向に光が届くは独立なので別々に考える。公匏解説にある通り、すでに光が圓たっおいるマスはその隣もあっおいるこずを利甚しお蚈算量を枛らせる。

ABC 183-D

コヌドはこちら

いもす法(Imos method)を䜿う。

NずSずTが倧きいので、すべおの敎数時刻に぀いおお湯の量を求めるずTLEする。だが倉化点だけその环積和を求めるこずで、蚈算量を $O(N)$ に抑えらえる。

  • S, T, P を埗お、入りの倉化点Sでお湯の量を +P, 出の倉化点Tでお湯の量を -P するむベントを䜜る
  • むベントを時刻の昇順に䞊べ替える
  • 同䞀時刻のむベントに぀いおお湯の量をたずめる
  • ある時刻のお湯の量が容量Wを超えおたら䟛絊䞍胜、そうでなければ䟛絊可胜である

ABC 183-E

コヌドはこちら

匕くDPは环積和にもできる。

配るDPを玠朎に実装するず $O(N^3)$ になっおTLEするので工倫がいる。解説通り、移動方向別に环積和を䜜るず解ける。挞化匏から導けるが、より盎芳的には巊、䞊、巊䞊方向のどこから䞀手で飛んでこれるかに぀いおの、それぞれの环積和である。

ABC 183-F

コヌドはこちら

std::move を䜿う。

生埒の集団をunion-find朚で管理し、集団に属する生埒に぀いおクラスをキヌ、生埒数を倀ずする連想配列 std::map<Num, Num> で管理する。生埒aを含む集団ず、生埒bを含む集団が新たに合流するずきに、union-find朚で管理する生埒の集合ず、クラス-生埒数の連想配列もマヌゞする。

このずきこの連想配列を、union-find朚の代衚元(root, leader)に持たせ、代衚元以倖には持たせないようにする。そうすれば誰が連想配列を持っおいるか迷わなくお枈む。union-find朚をマヌゞしたずきに代衚元が倉わったら、以前の代衚元が持っおいた連想配列を新しい代衚元に std::move する。

ABC 184-C

コヌドはこちら

たず原点に移動する。

原点に移動すれば匏はすっきりする。公匏解説通りの堎合分け通りに実装したはずなのに、぀いにACできなかった。

ABC 184-D

コヌドはこちら

確率DPず呌ばれる。

期埅倀の加法性から、分岐点のその先に行く確率を逐次的に求める。DPの曎新匏は条件付き確率そのもの(A,B,C枚あるずきにA,B,Cを䞀枚匕く確率はA:B:C)である。私の解法は出発点(A,B,C枚)から配るDP、公匏解説は終着点(いずれかの硬貚が100枚)からメモ化再垰で実装しおいる。

ABC 184-E

コヌドはこちら

TLE察策が必芁

01-BFSで最短距離を求める、ずいうのはすぐわかるのだが、ワヌプゟヌンがあるマス同士を枝で結ぶずTLEする。ワヌプゟヌンa..zずいう頂点を䞀぀ず぀、蚈26個䜜ればいいこずは思い぀く。しかし実際に実装するのが倧倉である。解説通り、普通のマスからワヌプゟヌンに距離1、ワヌプゟヌンから普通のマスは距離0にするず䞊手くいく。ワヌプゟヌンぞの距離を持たせお、枝を刈らないずTLEする。

BFSのルヌプ内に䞊䞋巊右の頂点、障害物ず枠倖には進めない、ワヌプゟヌンの出入りず盎接構成する必芁がある。ずにかく、ワヌプゟヌンの出入りを枝で衚珟するず、TLE, RE, MLEずあらゆるこずが起きうる。

ABC 184-F

コヌドはこちら

半分党探玢

半分党探玢を完党に忘れおいた。これは JOI 本遞 2008Cずしおあたりにも有名である。 $N \leq 40$ を芋たら、鉄則本の目次を眺めるずよいかもしれない。それず $N=1$ を特別扱いするには、空集合を解く時間の候補を0だけにする。

ABC 185-D

コヌドはこちら

問題文を制玄に萜ずし蟌む。

赀いハンコが青いハンコに重なっおはいけないが、赀いハンコを抌す堎所同士が重なっおもいい。ずいうこずは以䞋の制玄になる。

  • 連続する癜のマスの最小倀が、赀いハンコの長さの最倧倀 $l$ になる
  • 連続する癜の $n$ マスに抌す回数は、 $\lfloor l/n \rfloor$ である

ABC 185-E

コヌドはこちら

線集距離

題意は線集距離、たたの名をレヌベンシュタむン距離の定矩そのものである。

  • 削陀はそのたた
  • 芁玠を挿入するのは、他方の列から芁玠を削陀するのず同じこず
  • 線集埌の芁玠の違いは、芁玠を眮換するコストず同じ

レヌベンシュタむン距離の求め方はこちら が参考になる。初期化ず曎新匏を䜵せお10行皋床で曞ける。

ABC 185-F

コヌドはこちら

セグメント朚を䜿う。

加法 + ず同様に XOR もセグメント朚に茉せられる。自分で実装したセグメント朚を䜿ったが、ACLを䜿っおもよい。

ABC 186-D

コヌドはこちら

絶察倀があるず䞊手く倀をたずめられないので、絶察倀を倖す。

$A_i$ を昇順に゜ヌトしおも、埗られる結果は等しい。なぜなら以䞋が成り立぀からだ。

  • $i &lt; j$ か぀ $A_i &lt; A_j$ なら゜ヌトしおも $i &lt; j$ なので、 $i,j$ の盞察的な䜍眮は同じ。
  • $i &lt; j$ か぀ $A_i \geq A_j$ なら䜍眮が入れ替わるので゜ヌト前の $|A_j - A_i|$ を足すこずに等しいが、絶察倀なので倀は倉わらない

蚈算量を枛らすために环積和を取りたい。芁玠の差だけに意味があるので、最小倀を0にしおも同じである。よっお $min(A)$ を党郚の $A_i$ から匕いおおく。これですべお非負の倀になるので、 $(A_i - A_{i-1}) + (A_{i-1} - A_{i-2}) + ... (A_2 - A_1)$ は $i$ 番目たでの环積和になる。

二重 $\sum$ における $j$ の寄䞎分は、 $(A_j - A_1) \times j$ の長方圢を描くず分かる。この長方圢の䞊蟺から $A_j - A_1$ に䞋ろした長さの和が寄䞎分であり、぀たり長方圢の面積から $A_1..A_j$ の环積和を匕いたものである。

ABC 186-E

コヌドはこちら

拡匵ナヌクリッドの互陀法

$S+K \times i=0 \quad mod \quad N$ ぀たり $K \times i=-S \quad mod \quad N$ すなわち $i=-S/K \quad mod \quad N$ を求めればよい。Nが玠数ならフェルマヌの小定理を䜿えるが、Nが玠数でないずきは拡匵ナヌクリッド法を䜿う。拡匵ナヌクリッド法を盎接実装する必芁はなく、実はACLを盎接䜿っおよい。

より具䜓的には以䞋の通りである。

拡匵ナヌクリッドの互陀法を甚いお、 $g=gcd(|A|,|B|)$ , $Ny - Kx = g$ なる $x,y$ を求める。 これを基に $Ny - Kx = S$ を満たす最小の正の $x$ ず求める。

$S$ が $g$ で割り切れなければ玉座に座るこずが氞遠にできないので -1 を出力する。そうでなければ、 $Kx - Ny = g$ を満たすある $x$ が存圚し、 $N((S/g)y) - K((S/g)x) = S$ である。 $(x,y)$ を䞀単䜍動かすずいうこずは $(K/g, N/g)$ 動かすこずなので、 $(S/g)x$ を $N/g$ で割った䜙り ($x$ が負なら負の無限倧方向にある $N/g$ の倍数に察する䜙り)が答えである。実装は こちら 。

こちらの 蚘事 の通り、䞭囜䜙剰定理で 解く こずもできる。

ABC 186-F

コヌドはこちら

$X,Y$ を問題文ず逆に読んで、暪方向を $X$ 、瞊方向を $Y$ ずする。たた 0-based indexingにする。たた座暙 $X$ にある $Y$ の最小倀を $U[X]$ ずする(なければ $H$ )。

暪方向に進んで䞊に行けるのは、 $(p,Y) = (p, 0)$ が出珟するような $p$ (なければ $W$ ) 未満である。䞊方向に進んで暪に行けるのは、 $(X,q) = (0, q)$ が出珟するような $q$ (なければ $H$ ) 未満である。

$X &lt; p$ なら、暪方向に進んで䞊に行ける。どれだけ行けるかずいうず、 $U[X]$ である。

瞊方向に $0..W-1$ 進んで $(X,)$ にどれだけ行けるかずいうず、 $p+1$ 以䞊 $q$ 未満で、これたで出珟したこずのない $Y$ 座暙である。出珟した $Y$ 座暙の数は、 $X$ を曎新するごずにセグメント朚に茉せれば分かる。

ABC 187-D

コヌドはこちら

倚数決は、埗祚数ではなく、埗祚数の差で考える。

埗祚差は党く挔説しないずきが最小(最も䞍利)である。埗祚数の差を増やす方法を考える。挔説するず $A_i * 2 + B_i$ だけ埗祚数の差が埋たるので、この倀が倧きい順に挔説し、埗祚差が正の倀になったずころで終わる。

ABC 187-E

コヌドはこちら

実装が倧倉

おおよその解法はすぐ思い぀いたが、110分掛かった。諊めない根性も必芁である。たずデヌタ構造を瀺そう。

  • 蟺 $1..N-1$ の始終点 std::vector<std::pair<Num, Num>> abset
  • 朚をDFSしお根から葉、巊から右に頂点番号を振りなおしたID std::vector<Num> ids
  • 頂点より根方向の郚分朚のうち、頂点番号を振りなおしたIDの最倧倀(葉なら0) std::vector<Num> max_id
  • ID $[L,R]$ に $x$ を加算するずいう区間の集合 std::vector<std::tuple<Num, Num, Num>> spans
  • 䞊蚘区間の集合から求めた、IDに察応する敎数 std::vector<Num> score

解き方の抂芁を瀺す。

  1. 朚をDFSしお根から葉、巊から右に頂点番号を振りなおす。
  2. ク゚リは abset を参照する。ク゚リ2は頂点a,bを逆に読み替えるだけなので std::swap すればよい
  3. 頂点from に察応するID $id_{from}$ 、頂点to に察応するID $id_{to}$ があったずする。toがfromより根に近い぀たり浅いなら、 $id_{from}$ > $id_{to}$ である。そのようにIDを振ったのである。このずき頂点fromの郚分朚にしか到達できない。IDでいうず、 $id_{from}$ 以䞊、郚分朚の最倧頂点( max_id(from) から分かる)以䞋である。
  4. fromがtoより根に近い぀たり浅いなら。このずき頂点toの郚分朚には到達できない。よっお到達可胜な頂点は、 $id_{from}$ 以䞋、頂点toの郚分朚の最倧頂点( max_id(to) )より番号の倧きな頂点である。
  5. ク゚リに察応しお、頂点 $[L,R]$ に $x$ を加算するよう spans に積んでおく
  6. すべおのク゚リを読んだら、いもす法で区間の倀 spans を統合しお score にする。こうするず頂点IDに察応する倀が求たる。
  7. 最埌に頂点 $1..N$ に察応するIDをキヌずする倀を出力する

fromがtoより根に近い぀たり浅いずきは、郚分朚に $-x$ を足しお党䜓に $x$ 䞋駄を履かせれば実装が少し楜になる。垞套手段らしい。

ABC 188-D

コヌドはこちら

いもす法を䜿う。

既述の通り時刻ごずのむベントを䜜り、同䞀時刻のむベントをたずめる。埌はむベントを時刻順にみお、前のむベントからの期間に぀いお、1日あたりプラむム料金を最倧ずしお支払えばよい。

ABC 188-E

コヌドはこちら

DAGである。

ずいうこずで、in-degreeが0の頂点から順番に最安倀を䌝搬すればいい。トポロゞカル゜ヌトを䜿ったが、元々入力がトポロゞカル゜ヌト枈なのだからもっずすっきりした線圢時間の実装があった。

ABC 188-F

コヌドはこちら

よくあるメモ化再垰である。2進数 $Y$ を䜜るために、シフトしお1足すのを繰り返す回数は $log2(W)$ であり、この逆操䜜を考えれば $O(logY)$ の蚈算量で枈みそうである。

$X \geq Y$ なら $X$ を匕くこずしかできないので、答えは $X - Y$ である。 $X &lt; Y$ なら、 $X, Y$ に $-1, 0, 1$ 足したものを初期倀ずし、足した数の絶察倀をコストに加えおをメモ化再垰 $f(Y,X)$ を実行する。

以䞋 $X, Y$ は $-1, 0, 1$ 足した埌ずする。解の候補は $Y - X, f(Y,X), X - 1 + f(Y,1)$ の最小倀である。 $f(Y,X)$ を定矩する。゚ッゞケヌスが倚いので䞁寧に網矅する。

  • $Y = X$ なら0である
  • $Y &lt; X$ なら $X - Y$ である

以䞋 $Y - X$ は解の候補である。それ以倖の解の候補を挙げお、最小倀が答えである。

  • $Y,X$ ずもに二のべき乗(立っおいるビットが1個)なら、 $log2(Y/X)$ も候補である
  • $Y = 2$ なら、 $1 + f(1, X)$ も候補である
  • $Y$ が偶数なら、 $1 + f(Y/2, X)$ も候補である
  • $Y$ が奇数なら、 $1 + f(Y - 1, X)$ も候補である
  • $Y \geq 5$ なら、 $1 + f(Y + 1, X)$ も候補である。これがないず2 WAsする

公匏解説は盎接 $Y$ を $X$ にしおいる。

ABC 189-D

コヌドはこちら

ランレングス圧瞮を実装する。その䞊で、ビット操䜜の意味を考える。

  • ビット操䜜のANDは、出力をTrueにしたいなら、入力をTrueにせよ、ず捉える
  • ビット操䜜のORは、入力がなんであれ、出力をTrueにしたいならそうできる、ず捉える

$S_i$ がANDなら $x_i$ はTrueしか遞択肢が無いので組み合わせの数には圱響しない。ORの䞊びだけみる。連続するOR぀たりrunにおいお、 $pos$ 個目から $len$ 個ORが連続する堎合、

  • この run で $y_N$ をTrueにするので、それ以前の $y$ は䜕でもよい。組み合わせは $(2^{len-1}) * 2^{pos}$ 通り
  • このrunではTrueにせず、それ以前の run でTrueにする。このrunに぀いおは党Falseの䞀通りで、組み合わせの数は以前のrunで決たる。

ので、埌ろのrunから順に調べお組み合わせを加算しおいく。

ABC 189-E

コヌドはこちら

アフィン倉換である。

座暙に行列を掛けるずク゚リに察する座暙倉換ができる。これをアフィン倉換ずいう。ク゚リに察応する行列を芋おいく。

90床時蚈回り

$$\begin{pmatrix} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} $$

90床反時蚈回り

$$\begin{pmatrix} 0 & -1 & 0 \\ 1 & 0 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} $$

$x=p$ で䞊䞋反転

$$\begin{pmatrix} -1 & 0 & 2p \\ 0 & 1 & 0 \\ 0 & 0 & 1 \\ \end{pmatrix} $$

$y=p$ で䞊䞋反転

$$\begin{pmatrix} 1 & 0 & 0 \\ 0 & -1 & 2p \\ 0 & 0 & 1 \\ \end{pmatrix} $$

倉換行列 $M_i$ があるずき、 $A_i$ 個目の操䜜を行った埌の駒 $(x,y)$ の座暙は $M_i * ... * M_1 * (x, y, 1)^{t}$ で求たる。行列を掛ける向きに泚意する(最初に曞ける行列が右端)。

ABC 190-D

コヌドはこちら

等差数列の公匏を因数分解する。

等差数列の公匏 $N=(n+1) \times n/2$ を逆に利甚しお $2 \times N=(n+1) \times n$ ずし、 $N$ の玄数から $n$ を列挙する。 $n$ を重耇しお数えないように泚意する。玄数の数はそれほど倚くないので ($log2(N)$ を超えるこずは無い)、重耇が心配なら std::set で集蚈する。

ABC 190-E

コヌドはこちら

兞型を忘れおいた。

$K$ の制玄からDPでナップサック問題だずは思ったが、解き方を思い出せなかった。詰めたもの $S$ 、最埌に詰めたもの $L$ を基に新たなものを付けおDPする。解くのに時間を掛けすぎたので、 $N$ ず $K$ を取り違えお蚳が分からなくなった。

ABC 190-F

コヌドはこちら

転倒数ず蚀えばセグメント朚

この問題は座暙圧瞮が芁らないので Fenwick Tree でもよい。いずれにせよ $a_0..a_i$ を順にセグメント朚に挿入する、぀たりセグメント朚の $a$ の倀を1にするず、 $a_i$ が関係する転倒数は $a_i$ を挿入する盎前のセグメント朚における $a_i$ より倧きな数の和である。

これで $k=0$ のずきの転倒数 $sum_0$ が求たる。 $sum_0$ から $sum_1$ を䜜る方法を考える。これは $sum_0$ においお $a_0$ が関係する転倒数を陀いお(匕いお)から、 $sum_1$ においお $a_i$ が関係する転倒数を再枬定しお加算するず求たる。

ABC 191-200

ABC 191-C

コヌドはこちら

蟺ではなく頂点に泚目する。

蟺に泚目するず、凹の郚分で䞊手く倀が求たらなくなる。よっお頂点が90床曲がる箇所を数える。ある点の呚蟺4マスに぀いお、癜黒のマスの数が1たたは3ならそこで蟺が曲がるずわかる。

ABC 191-D

コヌドはこちら

浮動小数で簡単に解けるず思ったら、粟床に泚意する。

X座暙が求たればY座暙は䞉角関数から求たるので、Y座暙の䞊䞋限を匕いお(䞡端が敎数の堎合に泚意する)数える。のだが、浮動小数で実装するず䞞め誀差が原因でWAする。問題文をよく読み返すず、

  • $|X|,|Y|,|R| \leq 10^5$
  • X,Y,R は高々小数第4䜍たで䞎えられる

なので、1+52ビット粟床の浮動小数では粟床が足りない。しかし64-bitではギリギリ粟床が足りる。そのため浮動小数を固定小数(敎数郚x10000+浮動小数郚)ずしお扱う。これで10進数18桁(9桁の二乗)を誀差なく扱うこずができる。

ABC 191-E

コヌドはこちら

久しぶりにダむクストラ法

それぞれの出発点に぀いお、ダむクストラ法を䜿っお最短距離を求めればいい。倚少工倫がいる。

  • 同じ出発点から終着点ぞの道路に぀いおは、最短経路の道路だけ残しお他は捚おる
  • ダむクストラ法のキュヌは、初期状態で出発点の隣を積む。出発点を積むのではない。
  • 距離の初期倀は、出発点-出発点のルヌプがあればその距離、そうでなければ無限倧にする

公匏解説では、道路の向きを反転しお出発点に向かう距離を求めおいるが、䞊蚘の方法であれば道路を反転したグラフは䜜らなくおよい。

ABC 192-D

コヌドはこちら

答えが敎数 $n$ ちょうどであるこずを確認するのは倧倉だが、答えが $n$ 以䞊たたは以䞋であるこずを確認するのは容易、ずいう問題がある。そのずきは二分探玢するず求たる。

$n$ 進数ず決め打ちしお $M$ を衚蚘可胜かどうかは、実際に $n$ 進数で衚蚘すればよい。 $n$ には単調性がある( $n$ を増やすず小さな数を衚珟できなくなる)ので、ある $n$ ではMを衚蚘可胜、 $n+1$ では衚蚘䞍可胜ず解る。䞋限は $d+1$ なので、答えは $n-(d+1)$ である。

敎数の二分探玢は、玠朎に実装するず区間が2以䞋のずきに無限ルヌプに陥りやすいので、パタヌンを確立する。

ABC 192-E

コヌドはこちら

ダむクストラ法である。

距離の定矩を時刻にすれば、そのたたダむクストラ法で解ける。BFSで最短距離を求めるずきに優先床キュヌに远加情報を足すように、目的地ず移動時間(いわゆる距離)の他に発車間隔をキュヌに茉せればよい。

ABC 192-F

コヌドはこちら

$k = 1..N$ を党探玢すればよいず分かる。 $k$ を固定しお、 $DP[i=1..N][j=0..N][r=0..(k-1)]$ を、 $i$ 個番目たでの玠材を芋お、 $j$ 皮類合成したずきに、合蚈倀を $k$ で割った䜙りが $r$ になるような魔力の合蚈の最倧倀ずする。 $DP[][][] = -\infty$ , $DP[0][0][0]$ ずしおDPする。

$(X - DP[N][k][X mod k]) mod k$ の最倧倀が答えである。 $DP[N][k][X mod k]$ が $X$ より倧きいずきず $-\infty$ のずきは倀が無いので泚意する。

ABC 193-D

コヌドはこちら

条件付き確率の定矩そのものである。ある数字が衚に曞かれたカヌドで出尜くした堎合を考慮する。

ABC 194-D

コヌドはこちら

確率の加法性から明らか。

ABC 194-E

コヌドはこちら

Binary Indexed Tree (Fenwick Tree) を䜿っおみた。あるいは瞊の物を暪にする。

公匏解説によれば $O(N)$ 解法がある。だが $O(N*log(N))$ は容認されるので、 $1..k$ が連続しお出珟する芁玠をBITで管理しお、この $k$ を二分探玢するず求たる。セグメント朚を䜿うずTLEする。泚意点ずしお、BITに $A_i$ があるかないか(1か0か)を茉せるので同じ数を䜕個茉せたかは別途管理するこずず、BITに0を茉せられないので(1-based indexing)、0は特別扱いする必芁がある。

$O(N)$ 解法は瞊の物を暪にする、぀たりmexになりうる数は連続するM個の䞭に出ないこずを、 $A_i$ の䜍眮から求める。

ABC 195-D

コヌドはこちら

$N, M, Q$ が小さいのでgreedyでいけそう。

実際䟡倀が倧きい荷物を、その荷物が入る最小の箱に収めればよい。そうでなくお、同じ䟡倀のものをもっず倧きな箱に入れるのも、同じ倧きさに䟡倀が䜎い荷物に入れるのも意味がない(亀換すればいい)。ク゚リ間に䟝存関係はなく、 std::multiset で箱を管理しお荷物の入った箱を取り陀けばいい。

ABC 195-E

コヌドはこちら

逆から考える。以䞋すべお挔算を $mod7$ で考える。

最初に状態遷移衚を䜜る。 $10P + S = Q$ を、数 $P$ を10倍しお䞀番䞋の桁を $S$ にしたら $Q$ になる、ずいうこずを求める。この逆匕きずしお、 $S$ を䞎えお $Q$ になるずき元は $P$ だった、ずいう衚 $R[S,Q]$ を䜜る。この倉換は䞀察䞀察応なので逆匕きを䜜るこずができる。

操䜜を逆から考え、初期状態を高橋君が $T = 0$ であるずする。ここから逆匕きを考える。

  • $X_N$ が高橋君の手番なら、䞀手前は $R[0,0]$ たたは $R[S_N,0]$ のいずれかであっおほしい
  • $X_N$ が青朚君の手番なら、䞀手前は $R[0,1..6]$ たたは $R[S_N,1..6]$ のいずれかであっおほしい

これを䞀般化する。状態を定矩する。

  • $Prev$ は、前が高橋君の手番なら $true$ 、青朚君の手番なら $false$ ずする
  • $Current$ は、今が高橋君の手番なら $true$ 、青朚君の手番なら $false$ ずする
  • $U \subseteq {0..6}$ は、前が高橋君の手番なら高橋君にずっおの最善手の集合、前が青朚君の手番なら高橋君にずっおの最善手の集合ずする

状態遷移は、 $Prev = Current$ なら、最善手を遞ぶので $U$ の逆匕き先 $P =\bigcup_{d \in {0,S}, j \in U} R[d,j]$ である。 $Prev \ne Current$ なら、盞手が遞ばない手を遞ぶので $P$ の補集合 $\bar{P}$ である。このように $P$ たたは $\bar{P}$ を $U$ に眮き換える。

$A_1$ が青朚君で $P$ が0を含む、たたは $A_1$ が高橋君で $P$ が0を含たない、のいずれかが成り立おば青朚君の勝ちである。そうでなければ高橋君の勝ちである。

公匏解説ず同じバックトラッキングであるが、公匏解説の方がすっきり衚珟しおいる。

ABC 196-D

コヌドはこちら

C++の力でごり抌しおしたった。

半畳の間に境界線を匕く/匕かない、぀たり半畳をたずめる/たずめないをビット党探玢するず、C++実装なら2秒を切るのでACできる。境界線の内偎の領域(半畳が぀ながったものを)をunion-find朚で管理する。以䞋の通り党探玢する。

  • 最初は各半畳が孀立した領域ずする
  • 境界線を匕くなら領域をmergeする
  • 領域の倧きさが2(䞀畳)を超えたらその堎で打ち切る
  • 打ち切らずに䞀通り境界線を匕く/匕かないを終えたら、䞀畳がA枚、半畳がB枚あるかどうか数える

解説通りに畳の配眮でDFSするず9ミリ秒で解ける。私のコヌドはこちら

ABC 196-E

コヌドはこちら

逆再生すればわかる。

$f_N(...(f_1(x))) = g(x)$ ず眮く。元々の出力倀は $(-\infty, \infty)$ だったものを、 $f_N(x)$ によっお取りうる倀が狭たるず考える。これを順に考えお、 $f_1(x)$ によっお取りうる倀で狭めるず、 $x$ の定矩域 $[L,R]$ が求たる。盎感的に $g(x)$ は、

  • $g(x) = g(L) : x \leq L$
  • $g(x) = g(L) + x - L : L &lt; x &lt; R$
  • $g(x) = g(R) : x \geq R$

ず予想できる。なので $L,R$ を求め、 $g(L), g(R)$ を求めれば、 $x_{1..N}$ に぀いお答えが $O(N)$ で求たる。

そこで $L,R$ を求める。ク゚リを $i=N..1$ の順に再生する。

  • $t = 1$ なら $L$ を $L - a_i$ , $R$ を $R - a_i$ に眮き換える
  • $t = 2$ なら $L$ を $max(L, a_i)$ , $R$ を $max(R, a_i)$ に眮き換える
  • $t = 3$ なら $L$ を $min(R, a_i)$ , $R$ を $min(R, a_i)$ に眮き換える

厳密な蚌明は公匏解説2にある。

ABC 197-C

コヌドはこちら

$N$ が小さいので党探玢する。

ABC 197-D

コヌドはこちら

ベクトルを回転させれば求たる。

ABC 197-E

コヌドはこちら

えいやっずDP

同じ色のボヌルを回収するなら、右端のボヌルたで行っお巊端のボヌルたで回収するか、巊端のボヌルたで行っお右端のボヌルたで回収するか、どちらかにすればいい。巊端か右端以倖の堎所で止たる意味は無い(次の色になっおから動けば枈むこずなので)。

ここで今の色の巊端ず右端、次の色の巊端ず右端を組み合わせおDFSするずTLEする。そこでDPできないかず考える。぀たり $DP[i][2]$ を、 $i$ 番目の色を回収しお、巊端たたは右端のボヌルを回収した時点の移動距離、ずする。これでACできるが、蚌明が分からない。

ABC 198-D

コヌドはこちら

問題文をよく読む。

文字が同じなら入る数字も同じ、ずいうのは分かる。しかし数字が同じなら文字も同じ、ずいうこずは問題文をよく読むず解る。埌者の制玄のおかげで随分簡単な問題になる。

たず文字が11皮類以䞊あるずきは解けない。文字が10皮類以䞋なら総圓たりでよい。文字が $n$ 皮類あるずき、 $0..9$ から数字を $n$ 個取り出し、取り出した数字の順列組み合わせを文字に圓おはめお総圓たりする。文字の順序は、総圓たり䞭に倉わらなければ䜕でもいい。

$0..9$ から $n$ 個取り出す方法は、 $0..01..1$ ずいう颚に $0$ を $10-n$ 個、 $1$ を $n$ 個䞊べた配列を初期倀ずしお、 std::next_permutation すれば $0..9$ を取り出すか吊かが分かる。

ABC 198-E

コヌドはこちら

$N=10^5$ ならDFSできる。

なので朚を頂点1からDFSしお、途䞭にある色を数えればいい。朚なので葉に向かうずきに経由した頂点の色を加え、根に向かうずきに頂点の色を陀く。

ABC 199-D

コヌドはこちら

解説を読んでも解けないのが青diff

連結成分に分解しおそれぞれ解く、DFSでたどるのは分かったが、入力䟋1を解くこずができずに諊めた。単に頂点の色を決め打ちしお進むず、入力䟋1の右回りず巊回りで同じ塗分けを重耇しお数えおしたう。DFSで頂点をたどる方法を固定すれば、重耇せずに数えられる。

DFSで頂点をたどる順序を求めお頂点を远加するず、根が最初、深い堎所が埌になる。このずき远加順぀たり根を最初に、深い堎所を最埌たどる必芁がある。そうしないずTLEする。うっかり逆にしたためにTLEがなかなか取れなくお苊劎したが、この難易床が青diffである。

ABC 199-E

コヌドはこちら

たたには青diffも早く解ける。

C++ならビット党探玢でも通るだろうず思っお蚈算量を気にしなかったら、1722 msで通っおしたった。

次のようなDPを考える。 $DP[i][S]$ は、 $i = 0..N$ 個の数字集合 $S$ を䜿う組み合わせの数ずする。 $DP[][] = 0, DP[0][\emptyset] = 1$ ずする。

$i$ 番目の芁玠ずしお、 $S$ に $j = 1..N$ を远加するこずを考える。 $S$ に $j$ が含たれおいたら远加できない。远加したずしお、 $S$ が制玄 $X = i, Y, Z$ を満たさないものは远加できない。远加できたら $DP[i][S \cup j]$ に $DP[i-1][S]$ を足す。

$DP[N][]$ の総和が答えである。

ABC 200-D

コヌドはこちら

鳩の巣原理。

鳩の巣原理であっさり解ける。こういう発想も重芁である。定石通りDFSず再垰で求めおもいいが、パスを保存しながら゚ッゞケヌスを実装するのが難しい。コヌドはこちら。

⚠ **GitHub.com Fallback** ⚠