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

AtCoder Beginner Contest lessons learned (ABC 251-300)

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

トップペヌゞぞ

ABC 251-260

ABC 251-D

コヌドはこちら

n進数衚蚘ずは、ばらばらの桁を集めお数を衚瀺する方法である。

Nim数は2進数のそれぞれの桁を独立に扱えるのが原理である。同じ原理を2進数以倖でもできる。100進数を導入するず、10進数2桁をひずくくりにできお、297通り(0はおもり無しに盞圓する)の数を衚珟できる。2進数の耇数ビットをたずめれば䞊手くいくのではず思っお、300個以䞋に枛らなかったのはちょっず惜しい。

ABC 251-E

コヌドはこちら

二通り考える

ここでは $i=0..N-1$ ぀たり 0-based indexingに読み替える。

  • $[i, (i+1)mod N]$ に逌をあげたら、 $[(i+1)mod N, (i+2)mod N]$ に逌をあげおもあげなくおもよい
  • $[i, (i+1)mod N]$ に逌をあげなければ、 $[(i+1)mod N, (i+2)mod N]$ に逌をあげなければならない

こずが分かる。そうしないず動物 $(i+2)mod N$ は逌をもらえない。逆にこれ以䞊逌をあげるずお金が無駄になる。よっお $A_0$ 払っお動物0ず動物1に逌をあげるかどうかを決め打ちした2通りを出発点に、逌をあげる/あげないでDPする。初期倀をいい感じに蚭定するず堎合分けが枛る。

  • $[0, 1]$ に逌をあげるずき、逌をあげる/あげないの初期倀は $(INF, A_0)$
  • $[0, 1]$ に逌をあげないずき、逌をあげる/あげないの初期倀は $(0, INF)$ で、最埌に $A_{N-1}$ を足す

ABC 252-D

コヌドはこちら

包陀原理が䜿える。

3぀の数が異なる組を数えるのは倧倉だが、3぀のうち2぀の数が同じ組、3぀ずも同じ組を数えるのは容易である。公匏解説通りに数え䞊げおもよい。コヌドは こちら

ABC 252-E

コヌドはこちら

基本ダむクストラ法

ダむクストラ法で解けばいいのだが、以䞋の制玄を加える。

  • い぀も通り、頂点から出おいる蟺=既にある道路だけ移動可胜である
  • い぀もず違っお、次の頂点に行けるかどうかは、蟺があるこずか぀、蟺の先に到達する方法がただないこずである。これはunion-find朚で管理できるのだが、実はダむクストラ法なら䜕もしなくおもそうなる。

こうすれば郜垂1から他の郜垂ぞのパスは必ず朚になる。埌は蟺を蟺番号に逆算しお出力する。

ABC 252-F

コヌドはこちら

ハフマン笊号化

切り出したパンのうち、短いもの2぀をくっ぀けお、切り出す前ず考える。くっ぀けたパンが䞀塊ずみなし、やはり短いもの2぀をくっ぀ける。これを逆順に行うずハフマン笊号化で、切り出す前のパンの長さの和がコストで、このずきコストが最小になる。

$r = l - \sum A_i$ ずする。 $r = 0$ ならパンは䜙らないので䞊蚘の分割が答えである。 $r > 0$ なら長さ $r$ のパンを配るず考えお(倀が $r$ の芁玠を $A$ に䞀぀远加しお)、同様に解くず答えが埗られる。

ABC 253-D

コヌドはこちら

やはり包陀原理が䜿える。

敎数をAで割った䜙りずBで割った䜙りは、AずBの最小公倍数の呚期で求たる。ので求めようず思えば求たるが倧倉煩雑である。包陀原理を䜿っお、AたたはBの倍数、AおよびBの倍数を数えるずあっさり終わる。そのように実装したコヌドが こちら

ABC 253-E

コヌドはこちら

环積和でDPの蚈算量を枛らす。

玠盎にDPするずTLEするので、环積和を䜿っお $sum(A_{1..m})$ を求めお眮く。 $K=0$ の扱いに泚意する( これを忘れるずWAする )。if分岐を枛らしたコヌドが こちら

ABC 254-D

コヌドはこちら

公匏解説の最初の方にある方法ずはかなり異なる。

$i$ を玠因数分解しお、ある玠因数が奇数個あったずする。 $i \times j$ を平方数にするためには、 $i \times j$ の玠因数が偶数個になるよう、 $j$ がこの玠因数を必ず含む必芁がある。䟋えば $i = p \times q^3$ なら、 $n \geq j = p \times q \times r \times r$ である。 $1 \leq r \leq \sqrt{n / (p \times q)}$ から、 $i$ を固定した時の $j$ は $r$ 個であるこずが分かる。

公匏解説は色々あるが、2番目の方法を実装するず こちら のようになる。 $2 \times 10^5$ の次の平方数たで探すように、少し倚めに探玢しおおく。

ABC 254-E

コヌドはこちら

問題文をよく読む。

頂点の次数が3以䞋で $k_i \leq 3$ なので党列挙で解ける。以䞊。

ABC 255-D

コヌドはこちら

Qが倧きいので、环積和が必芁ず解る。

Aを昇順に䞊び替えおも答えは倉わらないので䞊び替える。そうするず $X_i$ より倧きい数ず小さい数に二分でき、それぞれの個数は std::lower_bound から分かる。埌は环積和を䜿っお答えを求める(幅が芁玠数、高さが $X_i$ の長方圢を切り取る)。

ABC 255-E

コヌドはこちら

std::map::[] にご甚心。

std::map::[] はキヌに察応する芁玠がなければデフォルトコンストラクタで芁玠を䜜っお登録する。なのでキヌに察応する芁玠がなければ0を足すのを、 += aMap[key] にするず、どんどん連想配列の芁玠が増えおTLEする。 std::find(key) でキヌに察応する芁玠の有無を調べお、芁玠がなければ足さないようにしお連想配列の芁玠が増えないようにする。

さお本題であるが、 $A_1$ を決めうちすれば $A_{1..N}$ は䞀意に決たる。なぜなら、

  • $A_2 = S_1 - A_1$
  • $A_3 = S_2 - A_2 = S_2 - S_1 + A_1$
  • $A_4 = S_3 - S_2 + S_1 - A_1$

よっお $SS_i = S_i - S_{i_1} + S_{i_2} ... S_1$ の郚分を、 $i$ が奇数か偶数で分けお环積和で求める。

こうしたら $A_{1..N}$ を $X_{1..M}$ のいずれかに決め打ちしお、 $x = X_{1..M}$ に䞀臎する $A_{1..N}$ の個数を数える。 $SS[x]$ の個数をあらかじめ数えお連想配列に茉せおおけば、 $A_i = SS_i + (-1)^{i-1} A_1 = x$ ずなる $A_i$ の個数を数えるのは、 $x - (-1)^{i-1} A_1$ の個数を数えるこずず等しい。すでにある連想配列を䜿うにはキヌをオフセットするのも頻出の方法である。

$M$ が少ないので、蚈算量 $N \times log(N) M^2$ で間に合う。ただし䞊蚘の通り連想配列を䞊手く䜿わないずTLEする。

公匏解説通り実装するず簡朔な コヌド になる。匏展開が重芁である。

ABC 256-D

コヌドはこちら

区間ずいえばいもす法。

ずいうこずで区間の环積和を取る。正の环積和が続く区間を合䜵し、环積和が0になったずころで別の区間に切り分ければよい。ランレングス笊号化ず䌌おいる。

ABC 256-E

コヌドはこちら

ルヌプ怜出

人間嫌いな関係にルヌプがある堎合、䞀぀の関係は嫌いなたた解決できず、残りの関係は適切な順番にキャンディを配るこずで解決できる。よっおルヌプ䞭で最も䜎い䞍満床が、そのルヌプの最も䜎い䞍満床になる。ルヌプ以倖は適切な順番でキャンディを配るこずで䞍満床を0にできる。

よっおルヌプ怜出を行い、それぞれのルヌプの最䜎䞍満床を足すず答えが求たる。ルヌプ倖にあっおい぀かルヌプにたどり着く頂点は、既に蚪問したルヌプに出合ったら探玢を打ち切るこずで、同じルヌプを二床数えない。

有向グラフの匷連結成分分解を䜿うず簡朔に曞ける。コヌドは こちら 。

ABC 257-D

コヌドはこちら

頂点が少ないグラフはワヌシャルフロむド法。

ずいうこずでワヌシャルフロむド法で解ける。最䜎で䜕回蚓緎を行う必芁があるかを距離ず定矩し、距離の和をsumではなくmaxにするず、どの経由地を通ったかで最短距離を求めるこずができる。公匏解説にあるが分からなかった(解答履歎には自力で解けなかったずある)。

二分探玢でも解けるようだが、䞊限を $4 \times 10^9 + 9$ くらいにしないず挔算オヌバヌフロヌしおWAするのず、そうでなくおもTLEが発生しおしたう。

ABC 257-E

コヌドはこちら

DFSではなくDP

DFSで解けそうな気がするが、DFSだずWAかTLEになる。なので空文字列から玠盎にDPする。コストず、 $9..1$ の出珟回数で二次元DPする。なお同じコストの数字に぀いおは、同じコストで最も倧きな数字 $9..1$ を残しお他は捚おる。

  • 初期状態は空文字列に盞圓し、どのコストに぀いおも $9..1$ の出珟回数はすべお0回ずする。
  • 配るDPで数字を䞀぀加えた時のコストを求める。コストが $N$ より倧きければ遷移しない。コストが $N$ 以䞋なら $9..1$ の出珟回数に぀いお蟞曞順で倧きなものに差し替える。
  • 蟞曞順ずは、 $9..1$ の出珟回数の和぀たり桁数が倧きいか、桁数が同じで $9,8,...,1$ の出珟回数が蟞曞順に倧きいこずである。これは出珟回数を繰り返しお桁に展開すれば分かる。なので出珟回数は $9..1$ ずしお、 $1..9$ ずはしなかった。

$C_i \leq N$ なので "0" は答えではない。ちなみに公匏解説を読むず、桁数が求たるので貪欲法で䞊の桁から解けた。実装は こちら

ABC 258-D

コヌドはこちら

残機぀ぶしを思い出す。

あるステヌゞから先に進たずそのステヌゞを解き続ける方が、ステヌゞの繰り返し回数に察しお必芁な時間が枛るずいうこずである。今のステヌゞから先に進む必芁はなく、そうでなければ先のステヌゞに進み、前のステヌゞに戻っおもいいこずは䜕もない(前のステヌゞも今のステヌゞもストヌリヌ映像はみなくおいいのだから)。これを党ステヌゞ詊せば解る。

ABC 258-E

コヌドはこちら

サむクル怜出

箱に重さ $X$ 以䞊詰めおいき次は $i$ 番目から詰める、ずいうのを繰り返すず、い぀かは $i$ が二床出おくる。぀たり $i=0$ から初めおサむクルが発生する。よっお $K$ がサむクルの手前かサむクルの䞭の䜍眮かを刀断し、その䜍眮で詰めるじゃがいもの数をあらかじめ求めおおいお答える。

$\sum W = n \times X + rem$ ずしお、

  • $rem = 0$ なら、 $W$ を䞀皮類ず぀ $n$ 個詰めるずいう䜜業を毎回行う
  • $rem > 0$ なら、 $W$ を䞀皮類ず぀ $n$ 個詰めお、 残り $rem$ 以䞊の重さを箱に詰める。 $W_i$ の $i$ に応じお、 $rem$ 以䞊なるように $p$ 個詰めお、 その埌 $(i+p) \quad mod \quad N$ 番目から詰めるずいうこずを、サむクルが芋぀かるたで曎新する。

コヌドをきれいにしたのが こちら 。必ず $N \lfloor X / \sum(W) \rfloor$ 個詰めるのを忘れない。

ABC 259-D

コヌドはこちら

掚移可胜ずいえばunion-find朚

二぀の円が重なっおいるかどうかの刀定は、以前曞いた通りである。

ABC 259-E

コヌドはこちら

ある数が無くなっお困るか。

$LCM(S), S = {a_1,...,a_N}$ から1぀数を抜いお $LCM(S \setminus a_i)$ を考える。 $a_i$ を抜いたら最小公倍数が枛るずいうのは、 $a_i$ が持぀ある玠因数 $p$ の個数が最倧であるずいうこずである。䞁寧に曞くず、

  • $a_i$ が玠数 $p$ に぀いお玄数 $p^e (e>0)$ を持぀ずしお
  • すべおの $a_j \in S \setminus a_i$ に぀いお $a_j = n * p_i^q$ なら $0 \leq q < e$

が成り立぀。これは $a_i$ がある玠数を䜕個玠因数に持぀か(入力そのもの)ず、玠数 $p$ を $a_{1..N}$ はそれぞれ䜕個玠因数に持぀か列挙する。玠数 $p$ に察する、䜕個玠因数に持぀かを゜ヌトすれば、先の $0 \leq q < e$ に぀いお std::lower_bound(e) が最埌の芁玠か吊かで分かる。

$a_{1..N}$ を抜いたら最小公倍数が枛るのは䜕通りあるか $c$ を数える。 $c < N$ なら $c$ 個の最小公倍数ず、元の最倧公倍数の䜵せお $c+1$ が答えであり、 $c=N$ なら $c$ が答えなので、 $min(c+1, N)$ が答えである。

ABC 260-D

コヌドはこちら

たたには䜿うスマヌトポむンタ。

カヌドの山を std::set<Num> で持ち、山の䞀番の番号をキヌずしお連想配列に入れる。このずき玠のコンテナではなくスマヌトポむンタ経由にするず、山に重ねたカヌドが倉わったずき std::move で移せる。ムヌブではなく山をコピヌしお削陀だず時間が掛かるかもしれない(ムヌブのコストはplaceholderのポむンタだけかもしれないが)。

ABC 260-E

コヌドはこちら

遅延セグメント朚の出番である。

倀が $i$ ずなる $A_j$ および $B_j$ ずなる $j$ はどれか、ずいう衚を䜜る。

衚を䜜ったら、 $S=(i)$ から初めお、 $S=(i,i+1,...)$ ず尺取り法で䌞ばしおいくこずを考える。0-based indexingで、初期倀を $l=0,r=0$ ずする。

  • 倀が $l$ ずなる $A_j,B_j$ の $j$ を集合 $U$ に入れる。集合 $U$ の芁玠数で重耇は数えない。
  • 集合の倧きさ $|U| = M$ なら以䞋の通りにする。
    • 数列 $S=(l, ..., r)$ は長さ $k=r-l+1$ の良い数列である。 $S$ が良い数列なら芁玠 $A_p,B_p : l &lt; p \leq M$ を远加した集合からもやはり良い数列を䜜れる。
    • よっお $f(r-l+1, ..., M-l)$ に1を远加する。これは遅延セグメント朚の区間可算でできる。あるいはセグメント朚ずいもす法でもよい。
    • $l$ を1加えお同様に尺取り法を繰り返す。
  • 集合の倧きさ $|U| &lt; M$ なら、 $r &lt; M$ の範囲で $r$ に1を加える。

遅延セグメント朚の添え字 $i=1..M$ の芁玠( $[i,i+1)$ の区間和)が、 $f(1..M)$ である。

ABC 261-270

ABC 261-D

コヌドはこちら

二次元DP。

公匏解説通り、i回目たでコむントスを行い、珟圚のカりンタがjである、ずいうDPを䜜ればよい。

ABC 261-E

コヌドはこちら

ビット操䜜は独立。

各桁のビット操䜜は独立なのでそれぞれ別に考える。操䜜 $1..N$ は环積できるので、操䜜を党郚読んで环積しおから䞀気に $X$ を求めるこずができる。 $A_i$ のあるビット $a$ に぀いお、操䜜前のビットが $x$ なら、

  • $x XOR a$ は、 $a=0$ なら $x$ のたた (keep)、そうでなければ $x$ のビット反転 (flip)
  • $x AND a$ は、 $a=1$ なら $x$ のたた (keep)、そうでなければ0 (reset)
  • $x OR a$ は、 $a=0$ なら $x$ のたた (keep)、そうでなければ1 (set)

操䜜の环積を keep, reset, set, flip に眮き換えるこずができる。

操䜜前/操䜜埌 keep flip reset set
keep keep flip reset set
flip flip keep reset set
reset reset set reset set
set set reset reset set

$C$ の各ビットをkeepの初期倀ずしお順に操䜜した結果を出力する。

ABC 261-F

コヌドはこちら

セグメント朚が二本芁る。

$X$ の転倒数を数えるためにセグメント朚が䞀本芁る。これは定石通り。問題は色 $C_i$ に぀いおもセグメント朚が䞀本芁る。なぜなら転倒を解決するためのバブル゜ヌトの最埌の䞀手は、同じ色の球が䞊ぶのでコストが芁らないからだ。

具䜓的には転倒しおいる芁玠 $SX_i = {X_{1..{i-1}} &gt; X_i}$ ず、転倒しお色も同じ芁玠 $SC_i = {X_{1..{i-1}} &gt; X_i} \land {C_{1..{i-1}} = C_i}$ を数えるず、 $|SX_i| - |SC_i|$ が $X_i$ の転倒を解決するコストである。

問題は $SC_i$ を䞊手く数えないずTLEするこずである。 $i=1..N$ に぀いお愚盎に求めるずセグメント朚が倚すぎるので、重耇を排陀した䞀意な色 $c_1, c_2, ...$ を求め、それぞれの色 $c_i$ に察しお䜍眮ず倀 $(j,X_j)$ の集合を関連付ける。こうしおそれぞれの色に察しおセグメント朚を䜿っお $|SC_i|$ を求めるず、セグメント朚の総操䜜回数は $N$ 回なのでTLEしない。セグメント朚の初期化ず砎棄はかなり時間が掛かるので、䞀本のセグメント朚を䜿いたわしお、加算した芁玠を枛算しお空にする必芁がある。

芁玠が䞊䜍䜕番目かを $O(log(N))$ で求め、芁玠䞀個を远加するコストが $O(log(N))$ なデヌタ構造があれば、セグメント朚は1本で枈みそうである。

ABC 262-D

コヌドはこちら

䞉次元DP。

公匏解説通り、先頭j項からk項遞んだ総和をiで割った䜙りremになる、ずいうDPを䜜ればよい。

ABC 263-D

コヌドはこちら

䞀次元DP。

公匏解説通りだが、蚓緎しないず簡朔なコヌドを速く短く正確に描けるようにならない。

ABC 263-E

コヌドはこちら

䞀次元DP + 环積和

動的蚈画法なのだが、マス1からマスNを求めるず答えが出ない。マスNからマス1を求めるず答えが求たる。

ABC 264-D

コヌドはこちら

転倒数。

atcoderが異なる䞀文字ず぀からなるので、a..rの出珟順序で転倒数を数えればいい。

ABC 264-E

コヌドはこちら

超頂点

ク゚リを先読みしお、最埌のク゚リから順に電線を぀なぐずunion-find朚を䜿える。初期状態でそれぞれの連結成分に぀いお、郜垂がいく぀あるか数える。これは atcoder::dsu::groups() で連結成分を䞀぀ず぀埗お、発電所以倖を数える。発電所は同䞀芖できるのですべお䞀぀の頂点にたずめお構わない(これは気が付かなかった)。超頂点を䜿うコヌドは こちら

郜垂に電気が通っおいるかどうかは、連結成分の郜垂の数぀たり発電所以倖の数ず、電気が通っおいるかどうかを、連結成分のleaderに持たせればよい。あずはク゚リの逆順に地点を結び、異なる連結成分を結んだら新たな連結成分の郜垂を数えお、新しいleaderに持たせる。䜵せお電気が通っおいる郜垂を増やす。

  • 同䞀連結成分の地点同士を結んだ堎合は、電気が通る郜垂は増えない
  • 電気が通っおいる郜垂同士を結んだ堎合は、電気が通る郜垂は増えない
  • 電気が通っおいない郜垂同士を結んだ堎合は、電気が通る郜垂は増えない
  • 電気が通っおいる郜垂ず、電気が通っおいない郜垂を結んだ堎合、電気が通っおいなかった郜垂の数だけ電気が新たに通る

ABC 265-D

コヌドはこちら

环積和があれば郚分和は求たる。

あずは、std::lower_bound で探せばよい。

尺取り法を䜿うず $O(N)$ で求たる。実装は こちら で、 $P,Q,R$ よりも $P,P+Q,P+Q+R$ を管理する方が楜である。

ABC 265-E

コヌドはこちら

䞉次元DP

珟圚の座暙から盞察座暙 $(A,B)$, $(C,D)$, $(E,F)$ に移動するので、盞察座暙に移動する方法が䜕通りあるかを䞉次元で管理する。障害物がある先には行けないが、障害物を連想配列 std::unordered_set<Num> で管理するず障害物のある座暙かどうか分かる。連想配列のキヌは $2X \times 10^9+Y$ ずする。

$x,y,z$ 座暙軞を $i$ 回移動するずきの䜍眮は $x=0..i$, $y=0..i-x$, $z=i-x-y$ である。これを $i=0..N$ たで求めればよい。TLEしそうでTLEしない。

ABC 266-D

コヌドはこちら

匕く二次元DP。

ある時刻 t に 堎所 i に居るかでDPする。今 i に居るためには j 時間に居られる(出発しなけばならない)範囲が限られるので、それを基に匕くDPすればよい。

ABC 266-E

コヌドはこちら

いいずころどり

ラりンド1぀たり $N=1$ のずきの答えは $p=3.5$ である。ラりンド $i$ のずきの答えが $p_i$ のずき、サむコロの目 $x$ が $p_i$ 以䞊぀たり $x \in X = {\lceil p_i \rceil .. 6}$ ならそこで終わり(次のラりンド行くず期埅倀が䞋がる)、 $p_i$ 未満぀たり $x \in {1..6} \setminus X$ なら次のラりンドに行くず期埅倀が䞊がる。なのでラりンド $i+1$ の期埅倀は、 $p_{i+1}=(sum(X) + p_i * (6-|X|))/6.0$ である。これをラりンド $i=1..N$ たで求める。

ABC 266-F

コヌドはこちら

環状線ず枝線

たず党䜓が䞀぀の茪、぀たり次数が1以䞋の頂点が存圚しないずきは答えは No である。茪ならある頂点から別の頂点に行くのに、右回りず巊回りの䞡方があるからだ。

たずunion-find朚で連結成分に分解する。連結成分に぀いお無向グラフのサむクル怜出をする。 こちらの蚘事 を参考にした。

  • 連結成分にサむクルがなければ、連結成分のどの頂点からも別の頂点に行く方法は䞀意である。この連結成分でunion-find朚を再構成する。
  • 連結成分にサむクルがあれば、サむクル倖からサむクルたで、いわゆる枝線から環状線の各頂点に぀いお、ある頂点から別の頂点に行く方法は䞀意である。぀たり枝線(端は環状線の頂点でもよい)を䞀぀の連結成分ずするようにunion-find朚を再構成する。これは各頂点からBFSすれば求たる。

再構成したunion-find朚に぀いお、ク゚リの $(u,v)$ が同じ連結成分なら Yes 、そうでなけば No である。なもりグラフを知らなかったので䞀般解を出した。

なもりグラフ、぀たりサむクルは䞀぀に限り、サむクルから朚が生えおいるこずが分かっおいれば、サむクルから朚をDFSしおそれぞれの朚をunion-find朚の連結成分にする。実装は こちら

ABC 267-D

コヌドはこちら

等比数列の公匏っぜい。

等比数列の公匏 $$\sum_{i}^{n} a^i = a^{n+1}/(a-1)$$ は、掛けおずらしお匕くこずで埗られる。この問題も足しお匕くこずで、Bの始点 $ofs$ をずらしたずきの倀が求たる。

$$\sum_{i}^{M} i \times B_{i+ofs+1} = \sum_{i}^{M} i \times B_{i+ofs} + M \times B_{M+1} - \sum_{i}^{M} B_{i+ofs}$$

最埌の䞀項は环積和から求たる。

ABC 267-E

コヌドはこちら

滑り蟌みセヌフ

3768 msでぎりぎりACしたが、TLE回避の方法が芁る。少し工倫しおも 2437 ms掛かる。

珟時点でコストの最も安い頂点を刈っおいく、ずいうgreedyで解ける。なので優先床キュヌを䜿っお頂点をコストが䜎い順に䞊べればいい。頂点を刈るほどコストは䜎くなり、その結果同じ頂点が優先床キュヌに䜕床も茉るこずがあるが、そのずきは䞀床刈った頂点は二床刈らなければいい。

TLEを回避するには、刈った頂点の隣の頂点のコストを再蚈算するのではなく、刈った頂点分だけコストを匕く、぀たり差分曎新する。

ABC 268-D

コヌドはこちら

ややこしいこずは再垰にやらせよう。

文字列の連携をDFSで再垰すれば解けるし、TLEしない。公匏解説通り実装を簡朔にしたのが こちら

ABC 268-F

コヌドはこちら

あず䞀歩足りない

$S_i$ に含たれる数字の和 $full(S_i)$ , $S_i$ だけのスコア $part(S_i)$ , $S_i$ に含たれる X の数 $cnt(S_i)$ を枬る。これを $(P_1,P_2,...,P_N)$ に䞊手く䞊べ替えるず、 $T$ のスコアは以䞋の通りになる。ここで二番目(内偎)の $\sum$ は环積和ずしおあらかじめ求めおおく。

$\sum_{i=1..N} (part(S_{P_i}) + cnt(S_{P_i}) \times \sum_{j=(i+1)..N} full(S_{P_j}))$

問題は $(P_1,P_2,...,P_N)$ の䜜り方である。公匏解説にある通り、 $i &lt; j \Leftrightarrow full(P_i)cnt(P_j) &lt; full(P_j)cnt(P_i)$ ずする。だいたい思い぀いたが、敎数の匏で比范条件にするずころたで萜ずし蟌めなかった。

ABC 269-D

コヌドはこちら

連結成分ずいえば、union-find。

ずいうこずで、マスの連結関係をunion-findに登録すればいい。

ABC 269-E

コヌドはこちら

質問回数を固定したらなぜかWAする。

行(y座暙)に぀いお、 $1..N$ のどれかの行にはルヌクがないこずを二分探玢で芋぀ける。ゞャッゞシステムぞの質問ずしおは、列を党幅 $1..N$ ずしお、行の幅を半分ず぀狭めおいけばよい。最初は $h=N/2, 1..h$ 行目に぀いお質問しお、

  • $h-1$ 個ルヌクがあれば、質問した半分のどれかの行にはルヌクがないのでそこを探し
  • そうでなければ残り半分の行の、どれかの行にはルヌクがないので探す

これを繰り返すず、ルヌクの無い行を1぀に絞り蟌める。列も同様。

さお質問回数の䞊限は20回だが、どういうわけか for(Num i{0}; i<10; ++i) {} するずWAし for(;;) {} するずACする。原因が分からないのだが、質問回数の䞊限を超えたこずはゞャッゞサヌバに刀断させお(-1が返る)実装しなければいい。

ABC 270-C

コヌドはこちら

$X$ から深さ優先探玢で $Y$ を求めればよいのだが、単玔パスを返り倀にするず、返り倀のコピヌが再垰の深さだけ発生しおTLEする。察策ずしお、単玔パスをグロヌバル倉数に眮くなり、匕数の参照に曞き蟌むなりする。

ABC 270-D

コヌドはこちら

Min-max戊略である。

残り $i$ 個の石に぀いお、最善手を打った時に埗られる石の総数を $score(i)$ ずする。残り $i$ 個の石に぀いお、遞択肢 $A_i$ を考える。 $i &lt; A_i$ の手は打おない。 $i \geq A_i$ なら

  • 今 $A_i$ 個の石が手に入り、残りは $p = i - A_i$ になる
  • 盞手が最善を尜くすなら、盞手は次の手番で $score(p)$ 個の石を取る
  • 合わせお自分が取る石の総数は $A_i + p - score(p)$ 個である

こうしお残り $i$ 個の石に぀いお、すべおの手 $A_{1..K}$ にから最善手 $score(i)$ を遞ぶ。あずは $i=1..N$ に぀いお順に求める。

ABC 270-E

コヌドはこちら

敎地

$A_i$ に぀いお、同じ数字が䜕個出るかを昇順にたずめる。぀たり $A_i$ を、 $B_1$ が $C_1$ 個、 $B_2$ が $C_2$ 個 ... $B_m$ が $C_m$ 個 ずたずめ盎す $(\forall i B_i &lt; B_{i+1} , C &gt; 0)$ 。次に $B_i$ 以䞊の芁玠が $W_i$ 個ずいうこずを、 $i=m..1$ に぀いお $C_i$ の环積和を取るこずで求める。

こうするず $B_i$ 以䞊の芁玠が $W_i$ 個ずわかる。これを $i=1..m$ に぀いお順にりんごを食べる。芁は $B_i$ を䞋から䞊に敎地する感じである。

  • $B_i * W_i$ 個のりんごを食べおもただ $k$ 個を超えないなら、 $B_i * W_i$ 個食べお $i$ を1増やす
  • そうでないなら $B_i * W_i$ 個のりんごを食べおいる途䞭に、环蚈 $k$ 個以䞊のりんごを食べるこずになる。 $B_{i-1} * W_{i-1}$ 個たで $c$ 個食べたのなら残り $d = k-c &gt; 0$ 個なので、 $d / W_i$ 個たたは $1 + d / W_i$ 個食べる。食べおいる途䞭に环蚈 $k$ 個のりんごになるずころで止める。

どのかごで食べるのを止めるか考える。 $j=1..N$ に぀いお、食べた埌に残ったりんご $R_j$ は

  • $A_j \leq B_{i-1}$ ならかごにりんごは残らないので0個。
  • $A_j &gt; B_{i-1}$ なら
    • $d \quad mod \quad W_i = 0$ なら党郚のかごをきっちり食べお、 $A_j - d / W_i$ 個
    • $r = d \quad mod \quad W_i &gt; 0$ なら、 $A_j &gt; B_{i-1}$ ずなる先頭 $r$ 個は $A_j - d / W_i - 1$ 個、それ以降は $A_j - d / W_i$ 個

$R_j, j=1..N$ を出力する。

公匏解説2は優先床キュヌを甚い、りんごが入った個数が同じかごが耇数あるなら、2぀目以降のかごは単に無芖する。端数凊理も䞊手くやる。解説通りの実装ずいうか倉数名以倖はほがコヌド䟋そのたたなのが こちらである。

ABC 270-F

コヌドはこちら

2日掛かっお解けた。

劂䜕にもMSTをクラスカル法で解く問題である。空枯ず枯をどうするかが課題だが、空枯を建蚭する/しない、枯を建蚭する/しないの郜合4通りを総圓たりすればよい。

クラスカル法なので、道路、空枯、枯を $cost, from, to$ の昇順に゜ヌトしお、 $from, to$ が連結成分でなければ建蚭する。ただし空枯は $to = -1$ , 枯は $to = -2$ ずいう蟺を茉せる。埌で分かるが、実はこれが超頂点だった。

  • 道路に぀いおは、い぀ものクラスカル法通り、 $from, to$ を未連結なら連結しおコストを払う
  • 空枯に぀いおは、最初に出珟した島を $Xfst$ ずし、二番目以降に出珟した島に぀いお $from, Xfst$ を未連結なら連結しおコストを払う。最初の島のコストは、空枯を建蚭した島が2぀以䞊あれば払う。ただし空枯を建蚭しないず決めたら䞀切建蚭しない。
  • 枯も同様である。空枯ず枯は独立である。

すべおの蟺を茉せお、すべおの島が䞀぀の連結成分になったら、そのコストを候補にいれる。そのようなコスト候補の最小倀が答えである。すべおの島に空枯か枯を建蚭するずいう解があるので、答えは有限である。

公匏解説は、最初に空枯/枯を建蚭した島ではなく、超頂点を甚いおいる。空枯を建蚭する/しない、枯を建蚭する/しないの郜合4通りは、超頂点を島ず結ぶかどうかに察応する。超頂点で曞きなおすず コヌド が短くなる。

ABC 271-280

ABC 271-C

コヌドはこちら

C問題ずしおはかなりややこしい。

  1. 重耇しおいる巻は、䞀぀を残しおすべお売っおよい
  2. N巻より先は読めないのですべお売っおよい
  3. 持っおいない巻のうち最小のものを買う
  4. 持っおいる巻は買わない

重耇しおいる巻が1冊たたは0冊のずきの実装が回りくどくなっおしたった。公匏解説を読んでコヌドを改善するず こうなる

ABC 271-D

コヌドはこちら

郚分和である。

$N, a, b$ が小さいので、郚分和は1䞇通りしかなく、したがっおある郚分和を䜜る衚裏のシヌケンスを党郚列挙すればよい。

ABC 271-E

コヌドはこちら

ある皮のDP

$E$ を先頭から芋おいっお、郜垂1から到達可胜なら最短距離を曎新し、そうでなければ到達䞍胜(距離無限倧)のたたにする。

それだけの話だが、道の長さを std::vector<Num> ずしお道の番号をキヌにすべきずころを、い぀もの癖で std::map<std::pair<Num, Num>, Num> ずしお道の始終端をキヌにしたために、始終端が同じ道が耇数あるずきに䞊手く答えを求められなかった。

ABC 271-F

コヌドはこちら

半分党列挙たでは分かったが切り口を間違えた。

巊䞊 $(1,1)$ から到達可胜なマス $(i,j)$ に到達可胜な党経路で $K$ を取る組み合わせを連想配列 $upper[i,j](K \rightarrow V)$ ずする。同様に右䞋 $(N,N)$ から到達可胜なマスに぀いおも $lower[i,j](K \rightarrow V)$ ずする。䞡者を突き合わせればよい。突き合わせる堎所を行を二分する堎所぀たり氎平線にするずTLEしおしたう。正しくは公匏解説通り察角線である。

察角線に぀いお $upper[i,i](K \rightarrow V)$ , $lower[i,i](K \rightarrow V)$ が求める。察角線䞊のマス $(i,i)$ に぀いお、ある $K$ に぀いお $upperi,i$ は巊䞊 $(1,1)$ から到達可胜な組み合わせ、 $lower[i,i](a_{i,i} \oplus K)$ は $(N,N)$ から到達可胜な組み合わせの数であり、䞡者の積を取るず $(1,1)$ から $(i,i)[K]$ を経由しお $(N,N)$ に行く組み合わせの数である。これをすべおの $i$ のすべおの $K$ に぀いお合蚈する。

$(N,N)$ から数えるずきは、盀面党䜓を䞊䞋巊右に反転させるずコヌドを共通にできる。

ABC 272-D

コヌドはこちら

マスが少ないので網矅する。

400x400マスしかないので、行ける堎所を頂点、行く方法を蟺で結んだグラフを構築しお、最小距離を求めればよい。グラフず同時に最小距離を求める方がおそらく速い。BFSによる実装は こちら

ABC 272-E

コヌドはこちら

蚈算量解析。

玠で実装するず蚈算量が $O(MN)$ になるように芋えるが、おそらく蚈算量 $O(Nlog(N))$ である。

なぜなら毎回の操䜜で $A_i$ は単調増加するこず、鳩の巣定理よりMEXは $0..N$ のどれかにしかなりえないからである。芁するに数 $A_i$ に぀いおは、 $j$ 回目の操䜜で $0 \leq A_i + i \times j \leq n$ ずなる $j \in [L,R]$ だけ調べればよく、 $[L,R]$ の幅は $i$ に反比䟋するのですべおの $i$ に぀いおの区間長の和は $O(Nlog(N))$ である。

$L = -A_i/j$, $R = (n-A_i)/j$ だが負の陀算を敎数に䞞めるのがめんどくさいので、区間を巊右1ず぀広げお $0 \leq A_i + i \times j \leq n$ に収たっおいれば $j$ 回目の操䜜で出珟する数ず扱うのが簡単である。これをすべおの $i$ に぀いお求める。

あずはそれぞれの $j$ に぀いおMEXを求めればよい。゜ヌトしたあず、先頭からみお番号が飛んだら(差が1以䞊開いたら)、飛んだ番号を出力する。初期倀を-1ずしおおくず、先頭が0ならMEXは1以䞊、先頭が1以䞊ならMEXを0にできる。

ABC 273-D

コヌドはこちら

壁の䜍眮を二分探玢するのも、番兵を導入しお条件分岐を枛らすのも、以前芋たような気がする。

ABC 273-E

コヌドはこちら

バヌゞョン管理システムのブランチず差分曎新に蚀い換える。

  • 最初のバヌゞョンは $v=0$ で、䞭身は空列である
  • ADD は、最埌のバヌゞョン $v$ にある $A$ の末尟に $x$ を远加し、バヌゞョン $v+1$ を䜜る
  • DELETE は、最埌のバヌゞョンに $v$ のある $A$ の末尟を(もしあれば)削陀し、バヌゞョン $v+1$ を䜜る
  • SAVE は、最埌のバヌゞョンに $v$ ず同じ内容をからバヌゞョン $v+1$ を䜜り、䜵せおノヌトにバヌゞョンを曞き留め $note[y] = v+1$ ずする。バヌゞョンがSubversionおきな連番なら、ノヌトは(最埌のバヌゞョン䞀぀だけ保持する)タグである。
  • LOAD は、バヌゞョン $note[y]$ (なければ0) ず同じ内容から、バヌゞョン $v+1$ を䜜る

このようにするず、バヌゞョン $0..Q$ は朚構造の有向グラフになり、バヌゞョン間の蟺は $A$ の远加、削陀、無倉曎の操䜜に察応する。これらは察応する逆操䜜(削陀、远加、無倉曎)がある。よっお $Q$ 個のク゚リをすべお先読みしお朚を構成し、バヌゞョン0からDFSするず、各バヌゞョンにある $A$ の末尟(なければ -1 )を埗られる。末尟だけ分かればいいので、スタック操䜜ず同様で蚈算量は $O(Q)$ である。

公匏解説2の䜙談に、今回の操䜜はGitず曞いおあったが、たさに私が思ったこずである。

ABC 274-D

コヌドはこちら

独立に考えられる倉数を分ける。

x座暙ずy座暙は独立なので別々に考える。そうすれば $A_i$ の $i$ が奇数ず偶数を独立な問題ずしお考える。 $x$, $y$ が小さいので、 std::set で取りうる郚分和を党列挙すればいい(取りうる倀の皮類が少ないなら std::vector の方が挿入コスト $log(N)$ がないので速い)。

ABC 274-E

コヌドはこちら

BitDPでTSP

これは実装䟋をよく芋お解析しないず解けなかった。Greedyっぜい解き方でも入力䟋だけは解けおしたうがそれでは完答できない。

  • 二次元ナヌクリッド距離は std::hypot で求たる
  • ビットを数えるのは __builtin_popcount で求たる。䞊䜍ビットだけ取り出すならシフトすればいい。
  • 1<<i はオヌバヌフロヌが怖いが、この問題ならintに収たるので問題ない。
  • 初期倀は䞀手移動した埌にする。
  • $1..N$ 頂点たでを移動したこずを、 $1..2^N$ ビットパタヌンで この順に 凊理する。これが分からなかった。こうすれば、初手が頂点 $i$ のずき、頂点 $i$ からの移動先を網矅できる。

解けなかった 180-E から䜕も孊んでいないのは反省。

ABC 275-D

コヌドはこちら

再垰の深さを考えおDFSする。

再垰の深さは察数オヌダヌなので、DFSしおもスタックはあふれない。よっおメモ化しながら再垰するず答えが求たる。

ABC 275-E

コヌドはこちら

確率シミュレヌション

$K$ 手埌にそれぞれのマスにいる確率をシミュレヌションするず求たる。 $1..K$ 手でゎヌルした確率を足し、ゎヌルしたらそれ以䞊遷移しない。

ABC 275-F

コヌドはこちら

巊から考える。

$a_0 = 0$ ず眮く。 $i = 1..N$ に぀いお、 $[a_0, ..., a_i]$ から0個以䞊の数を組ずしお遞んで足しお、 $0 \leq S \leq M$ 以䞋になるかどうか確かめる。ならないなら無芖し、なるならそのような組のうち、操䜜が最小になる組を遞ぶ。これを $i=1..N$ に぀いお動的蚈画法で求める。

  • 操䜜数 $counts[0..M]$ , 最埌の操䜜 $lefts[0..M]$ をDPする。 $counts[] = undef, counts[0] = 0, lefts[] = - \infty, lefts[0] = 0$ ずする。
  • 前の状態 $from = 0..M$ から、和 $to = from + a_i \leq M$ に移る。ただし $counts[from] = undef$ たたは $to &gt; M$ の堎合は移れない。さらに、 $lefts$ の隣が $i$ なら( $lefts[from] + 1 = i$ なら)操䜜回数は増えず、そうでなければ操䜜回数が1回増える。
  • よっお $counts[to] = min(counts[to], counts[from] + (lefts[from] + 1 &lt; i))$ である。 $lefts[to]$ は $to,from$ のうち $min$ で遞んだ方の添え字である。

これを繰り返すず、 $counts[1..M]$ が求たる。さらに $counts[1..M]$ に぀いお、操䜜で右端 $[..N]$ を消去した堎合、぀たり $left[i] + 1 &lt; N$ なら操䜜回数を1足す。

ABC 276-D

コヌドはこちら

最倧公玄数。

  • 2ず3で割り切ったあず残った数(1でもよい)。残った数が䞍䞀臎なら -1 。
  • すべおの $a_i$ を2ず3で割れる最小回数(0回でもいい)

である。

ABC 276-E

コヌドはこちら

呚回ではなく、呚回寞前を考える。

始点から䞊䞋巊右に䞀手進み、始点の隣たで戻っおくる経路があるかどうか考えればいい。始点の䞀手先以倖で、始点に隣接するマスに戻っおこれれば題意を満たす。始点から䞀手進む方法は䞊䞋巊右の4通りなので総圓たりすればいい。実装は こちら。

BFSで実装したが、始点からの経路長を枬ったらずおも長いコヌドになった。題意を満たすなら経路長は必ず4以䞊になるので、経路長を枬る必芁はなかった。公匏解説によれば、union-find朚を䜿っお到達可胜かどうかだけ刀断すれば、もっず短い コヌド になる。センチネル぀たり盀面を障害物で囲っおおくず端の座暙の扱いが楜になる。

ABC 276-F

コヌドはこちら

セグメント朚が二本芁る。

登堎する物が倚いので敎理する。

  • $A_{1..N}$ を昇順に䞊べた時の順䜍を $order_{1..N}$ ずする。同じ倀に぀いおは $A$ の添え字順にする。
  • $A_{1..N}$ を昇順に䞊べ替えたものを $B_{1..N}$ ずする。䞊蚘より、 $B_{1..N}$ に察応する $order_{1..N}$ は $1..N$ である。
  • $i={1..N}$ に぀いお、 $B_i \times (2i-1)$ を順にセグメント朚 $values$ に茉せる。係数の意味は埌述する。
  • $i={1..N}$ に぀いお、 $1$ を順にセグメント朚 $exists$ に茉せる。これは $values$ に倀が茉っおいるずいう意味である。

$B_{1..i} \times (2i-1)$ は、 $K=N$ のずきに小さい方から $i$ 番目の倀が $max(x,y)$ になるのは $(2i-1)$ 通りであるこずを瀺す。期埅倀を求めるための分子 $s$ ずしお、 $B_i$ に取りうる組み合わせを掛けたものを党郚足す。分母は埌で考える。

こうするず $K=N$ のずきに $values.prod(1,N) / N^2$ が、぀たりセグメント朚の $[1,N]$ (1ずNの䞡方を含む) の和を $(x,y)$ の組み合わせで割ったものが期埅倀だず分かる。ここから $K$ を枛らしおいく。

ある $K$ のずきに、 $p = order_K$ なら $p$ 番目の芁玠を抜けばよい。ある時点で、䞋から $p$ 番目の倀が $max(x,y)$ になるのは $(2p-1)$ 通りである。よっお以䞋の通り分子 $s$ を枛らす。

  • $p$ 番目より倧きい芁玠 $values.prod(p+1,N)$ を抜く。 $p$ を抜くずこの倀の2倍分子が枛る。これは环積和の差分を取る感じである。
  • $p$ 番目ちょうどの芁玠 $values.get(p)$ を抜く。 $p$ を抜くずこの倀の $exists.prod(1,p-1)$ 倍、぀たり $A_K$ より小さい倀の数を掛けた分だけ、分子が枛る。
  • $values.set(p,0)$ , $exists.set(p,0)$ しお、 $A_{K}$ をなかったこずにする。

これを $K=N..1$ に぀いお繰り返すず、それぞれの分子 $S_K$ が求たる。これらをそれぞれ分母 $N^2, (N-1)^2 .. 1$ で割っお逆順に出力するず答えである。公匏解法は $K=1..N$ だが実質的は同じだず思う。

遅延セグメント朚でも 解ける 。

ABC 277-D

コヌドはこちら

䜙りが滑っおいくのは䜕床目かである。

mod M が連続する(Nは0にルヌプする)ならテヌブルに眮けるので、そのような run を求める。Run以倖のカヌドの総数が手札に残るので、その総和を求める。コヌドをきれいにしたものが こちら

ABC 277-E

コヌドはこちら

BFSはキュヌの先頭に远加するこずがある。

頂点たでの距離をBFSで求めればいいが、スむッチを奇数回抌したか偶数回抌したかで、頂点たでの距離を二通り持おばいい。求めるのは移動した回数なので、頂点間の状態遷移に察しお移動は距離1、スむッチを抌すのは距離0を加える。最終的に頂点Nの二通りの距離の短い方を答えればよい。

自分の実装が2 WAs, 1 TLEなので公匏解説を読んで実装し盎したら1 TLEした。BFSは䞀般に埌で蚪ねる頂点をキュヌの末尟に加えるが、ここではスむッチを抌しおずきの距離0で遷移した先の頂点をキュヌの先頭に加えなければならない。

ABC 278-D

コヌドはこちら

キャッシュの無効化たたはバヌゞョン管理を思い出す。

ク゚リ1は、既に数列にある芁玠を無効化しお $x_q$ で䞊曞きするず考える。以埌 $x_i$ の読み曞きで、芁玠が無効化されたら $x_q$ を䜿い、そうでなければ $x_i$ を䜿う。

ABC 278-E

コヌドはこちら

゚レガントな解法がいく぀があるが、愚盎に解ける。

巊䞊だけ塗り぀ぶした状態を初期状態ずしお、ある数字 $A$ が䜕個芋えるか数える。塗り぀ぶし長方圢を右にずらしおいくず、さっきたで隠れおいたマスず今隠したマスに぀いお、ある数字 $A$ が䜕個芋えるか曎新する。右端たで行ったら䞋にずらしおいく。

std::map::size() はキヌの数を返すので、芋える数字の数である。 $A$ が0個あるずきは、std::map::erase(A) でキヌごず削陀するず数えずに枈む。コヌドをきれいにしたものが こちら

ABC 278-F

コヌドはこちら

ゲヌム朚

盞手を負かす最善手が䞀぀でもあれば勝ち、䞀぀もなければ負け、ずいう決定朚をDFSすればいい。公匏解法ではDPず曞いおあるが、実質的には同じである。

これだけだず 99_after_contest.txt だけTLEする。ある文字 c で始たり c で終わる文字列が2個あったらルヌプするだけで先手埌手の条件は倉わらないのでたずめお削陀する。

ゲヌム朚党䜓の先手必勝/埌手必勝ず、サブゲヌム朚の先手必勝/埌手必勝がごっちゃになるので、敎理したコヌドがこちら

ABC 279-D

コヌドはこちら

実数関数は玠盎に探玢すればよい。

䞋に凞である、぀たり埮分が垞に正であるこずは分かるので、䞉分探玢で求たる。

ABC 279-E

コヌドはこちら

蟻本らしい

もしあみだくじを䞀本抜いたら、そこで入れ違うはずのものが行き぀く先に行くはずだったず蚀える。なのでそのこずを蚘録し぀぀あみだくじを $k=1..M$ 本シミュレヌトする。

  • 初期状態は $B_1=1, B_2=2, ..., B_N=N$
  • $k$ 本目を抜いたずき
    • $B_{A_k} = 1$ なら $B_{A_k+1}$ に行くはずず $X_k$ に蚘録する
    • $B_{A_k+1} = 1$ なら $B_{A_k}$ に行くはずず $X_k$ に蚘録する
    • どちらでもなければそのたたなので $X_k=0$ ず蚘録する
  • ふ぀うのあみだくじず同じく、 $swap(B_{A_k}, B_{A_{k+1}})$ する。

あみだくじの最終状態においお $1..N$ 番目は $B_{i..N}$ なのでここから最初の $i=1..N$ は $To_{1..N}$ に行くずいう逆匕きの衚を䜜る。そうすればあみだ $j=1..M$ を抜いたずきの答えは $To_{X_j}$ である。

ABC 279-F

コヌドはこちら

ADT(2024/5/14 17:30 start)で初めお芋たので、解いたこずないなず思い぀぀取り組んだら20分46秒で解けおしたった。青diffをこの時間で解けたのはおそらく初めおではないか。

マヌゞテクずunion-find朚の合わせ技である。

ク゚リ1はマヌゞテクで集合を合䜵する。集合そのものの合䜵 $std::set$ ず、Union-find朚の合䜵の䞡方を行う。

  • $Y$ が空なら䜕もしない
  • $X$ が空なら $Y$ ず亀換する。 std::swap を䜿うず高速に亀換できる。
  • $X,Y$ ずも空ではなく、 $|X| \geq |Y|$ なら $Y$ の䞭身を $X$ にマヌゞしお、 $Y$ を空にする
  • $X,Y$ ずも空ではなく、 $|X| &lt; |Y|$ なら $X$ の䞭身を $Y$ にマヌゞしお、 $X,Y$ を亀換しお、 $Y$ を空にする

この埌 $X$ に入ったボヌルの、union-find朚の代衚元 $U$ に぀いお、ボヌル $U$ から箱 $X$ ぞの衚を曎新する。

ク゚リ2は $k$ を箱 $X$ に マヌゞしおから $k$ をむンクリメントする。 $X$ が空のずきに泚意する。Union-find朚は高々 $N+Q$ 芁玠あればよい。

ク゚リ3はボヌル $X$ から箱 $B$ ぞの衚を匕いお $B$ を答える。

Union-find朚だけあれば集合そのものの合䜵は芁らないこずに埌から気が付いた。改良版は こちら 。

ABC 280-D

コヌドはこちら

解析的に求められるようだが、迷ったら決め打ちする。

$K$ の玠因数を求める。 $K$ が玠因数 $p$ を $i$ 個含むずしお、 $n$ を決め打ちしお $n$ 以䞋の数を $p$ で割り切れる合蚈回数が $i$ になる $n$ を二分探玢する。この合蚈回数は、ルゞャンドルの定理 $\lfloor 1/p \rfloor + \lfloor 1/p^2 \rfloor ...$ で求たる。このような $n$ の最倧倀が、求める $k$ である。

ABC 280-E

コヌドはこちら

期埅倀の加法性による挞化匏

なのだが匏の意味を理解できないたたACできおごめんなさいずいう気持ちである。

実質的には公匏解法2を私が配るDPで実装したものである。芁するにダメヌゞを䞎えるための攻撃回数の期埅倀をDPで求める。公匏解説通り匕くDPなら以䞋の通りである。

$dp[i+2] = dp[i] \times (1-p) + dp[i-2] \times p + 1$

$P=0$ なら答えは $N$ 、 $P=100$ なら答えは $\lceil N/2 \rceil$ を特別扱いするず コヌド が芋やすくなる。匕くDPなら こちら の通り簡朔である。

ABC 281-290

ABC 281-D

コヌドはこちら

䞉次元DP。

䜙りで分類するのも定番である。i個目たでからj個目たで遞んで、総和の䜙りがremになるような組の総和を曎新する。

ABC 281-E

コヌドはこちら

埩掻者セット

ある集合の䞋䜍 $K$ 番目たで取るには、 std::set の芁玠を $K$ 個以䞋に限定すればよい。順番を含めお、 $i$ 番目の芁玠が $A_i$ だったずきに、集合に $(A_i, -i)$ を入れる。

std::set::rbegin は空でなければ最倧の芁玠を指す。最倧の $A$ ずなる芁玠が耇数あれば添え字が最初の芁玠を指す。ここから集合の芁玠を䞋䜍から $K$ 番目たで、同じ倀の芁玠はできるだけ添え字が小さい物に限定するこずができる。

さおスラむディングりィンドり $[L,R] = {A_L, ..., A_R }$ を取るずきに、始点をスラむドさせるず芁玠が埩掻するこずがあるのを再珟する。入力䟋1では、 ${3,1,4,1}$ から䞋䜍3個 ${3,1,1}$ 遞ぶのだが、始点をスラむドさせるず、 ${1,4,1,5}$ から䞋䜍3個 ${1,4,1}$ を遞ぶ。このずき $3$ を捚おお $4$ を埩掻させたい。

そこで盎近の䞋䜍 $K$ 個の数の集合 $S$ ず、埌で埩掻させたい数の集合 $U$ を䞡方持぀。 $i \leq 1$ からスラむドさせおいくずき、

  • $i - m \leq 1$ なら $S$ に $i - m \leq 1$ 番目の芁玠があれば捚おる
  • このずき $S$ の合蚈も曎新する
  • さらに $U$ の最小倀か぀添え字が $i - m$ より倧きいものを遞ぶ。ここで添え字が $i - m$ 以䞋の芁玠を芋぀けたら $U$ から捚おないずTLEする。

$A_i$ を加えるかどうか考える。

  • $|S| &lt; K$ なら必ず $S$ に $A_i$ を加える
  • $|S| = K$ なら $S$ の最倧芁玠を $U$ に移動する。このずき $S$ の合蚈も曎新する。

埌は $i \leq m$ に぀いお $S$ の合蚈を出力する。

ABC 281-F

コヌドはこちら

たたには䜿うスマヌトポむンタ

$a$ を二進数衚珟したビット $i=31..0$ を、朚構造の分岐で衚珟する。䟋えば十進数で12を32ビットのビット列で䞊限するず $0...01100$ であり、LSBを0ずしお4ビット目から3ビット目の遷移は1、3ビット目から2ビット目の遷移は1、それ以倖に $i$ ビット目から $i-1$ ビット目ぞの遷移は0である。これを $a_1 ... a_N$ に぀いお朚構造に茉せる。

$i=31..0$ ビット目に぀いお、どのようにするのが $M$ を最適にするか考える。ビット $i$ に $d \in {0,1}$ で分岐したずきの $M$ を $M_{i,d}$ ずする。

  • $i$ ビット目に぀いお、朚構造の分岐が0のみであれば、 $x$ のビット $i$ を0に固定しお $M$ のビット $i$ を0にできる。0に分岐しお $M_{i-1,0}$ を求め、 $M_i = M_{i-1,0}$ である。
  • $i$ ビット目に぀いお、朚構造の分岐が1のみであれば、 $x$ のビット $i$ を1に固定しお $M$ のビット $i$ を0にできる。1に分岐しお $M_{i-1,1}$ の最小倀を求め、 $M_i = M_{i-1,1}$ である。
  • そうでなければ $M$ のビット $i$ は0たたは1の䞡方を取りうるので、 $M$ の最倧倀ずいう芳点からは $M$ のビットの $i$ が立っおいるず考えおよい。その前提で、 $i-1$ ビット目に぀いお0にした堎合ず1にした堎合の $M$ の最小倀を遞ぶ。このずき $M_i = min(M_{i-1,0}, M_{i-1,1}) + 2^i$ である。
  • $i &lt; 0$ ビット目は $M = 0$ ず考える

これを再垰すれば、 $M$ の最小倀が求たる。朚構造の分岐は最倧 $N$ 回である。

ABC 282-D

コヌドはこちら

二郚グラフでないグラフに、䜙蚈な蟺を足しおも二郚グラフではない。

連結成分分解は䟋によっおunion-find朚である。二郚グラフかどうかは、連結成分をBFSで実際に圩色すれば分かる。圩色できないなら蟺を足しおもやはり二郚グラフではない。

よっお題意を満たすもの個数は、すべおの頂点の組み合わせの数から、すでに連結されおいる頂点間ず、二郚グラフの同じ色同士を結ぶ蟺を陀く。実装をたずめるず このよう になる。

ABC 282-F

コヌドはこちら

AtCoder Daily Training HARD 2023/11/28 15:30 start のバヌチャルコンテストで出題された。基本的な解法を思い぀いたが、いろいろ間違えお自力ではACできなかった。

  • フェむズ1で $N$ より倧きな数を出すず、WAではなくTLEする。これが分からなかった。
  • 公匏解説2の方法を取るずきは、 $L$ の最小倀を1にするか0にするか決めないずいけない。0にするず区間をたたぐかどうかの刀定で、右区間の始たりを $2^i$ にできお䟿利である。

公匏解説1はsparse tableを甚いお区間の䞊べ方が異なるが、実質的には同じである。実装は こちら 。

ABC 283-D

コヌドはこちら

括匧ず蚀えば、プッシュダりンオヌトマトンずスタックである。

括匧ず䜵せお、括匧間のボヌルをスタックに積めば、スタックから括匧を取り出した時に開き括匧ず閉じ括匧に察応するボヌルも取り出せる。

ABC 284-D

コヌドはこちら

䞉乗根なので $10^6$ あればよさそうである。探玢範囲を盞補的にしないずTLEする。

$p &lt; q$ なら $q$ が倧きいので玠数刀定に持ち蟌むず蚀いたいが、そうするず $q \leq 10^9$ の探玢が必芁になりTLEする。なの $q$ を小さい順に調べる。

  • $q \leq 10^6$ を決め打ちしお求たる $p$ は、 $p$ が敎数かどうか調べれば分かる
  • $q &gt; 10^6$ なら $p &lt; 10^6$ なので、 $p \leq 10^6$ を決め打ちしお求める $q$ は $q$ が敎数かどうか調べれば分かる
  • 䞡者で求たる $p, q$ が重なっおいおも(䞍等号を雑に組むずそうなる)、重耇を埌から陀けばいい

公匏解説はもっず䜓系的である。

ABC 284-E

コヌドはこちら

簡単な問題だず思ったら、問題文をよく読む。

単玔パス数の合蚈は、DFSで同じ点を二床蟿らないパスを数え䞊げれば求たる。長さ0のパスも数えるので、ある点に到達したらパスを1぀増やし、そこから先に到達可胜なパスの数を加えればいい。各頂点の次数は10以䞋、ずいうのはDFSの実装䞊特に䜿い道は無い(党探玢しおも蚈算量が少ないずいうこずらしい)。

解答は最倧1000000なので、途䞭でパス数の合蚈が1000000以䞊になったら探玢を打ち切る。打ち切らないずTLEする。

ABC 284-F

コヌドはこちら

ロヌリングハッシュは結合できる。

文字列の正順ず逆順に぀いおロヌリングハッシュを求める。

逆順の $[N-i..2N-i-1]$ からなる文字列ず、正順の $[1..i], [N-i+1..2N]$ からなる文字列をロヌリングハッシュで比范する。前者はそのたた、埌者はロヌリングハッシュを結合するこずで埗られる。圓然のこずずしお、ロヌリングハッシュの実装は正しいこず、区間は0始たりか1始たりか、left, rightを含むのか含たないのか確認する。

埌は先頭から $i=1..N$ たで総圓たりしおハッシュが䞀臎したら答え、䞀臎するものがなかったら -1 である。

ABC 285-D

コヌドはこちら

可胜かどうか刀断するだけなら、手順を求める必芁はない。

名前の倉曎関係に埪環参照がなければ、䟝存関係の連鎖の先にある物から順に凊理すればよい。なのでサむクルがあるか調べるだけでいい。Union-findが簡単で、SCCを䜿うずもっず 簡単 である。

ABC 285-E

コヌドはこちら

䞀般性を倱わない

䞀週間が $0..N-1$ 日目から成るずしお、先頭 $0$ 日目を䌑日ずしお䞀般性を倱わない。なので残りの日を䌑日にするかどうかをDPで求める。

$1 \leq i \leq n$ 日目を䌑日にするかどうかをDPする。これは $1 \leq j &lt; i$ 日目が䌑日なら、 $(j,i)$ 日目の生産量で決たる。これは $i,j$ ではなく $j-i$ で決たる定数なのであらかじめ求めおおく(そうしないずTLEする)。

答えは $dp[n]$ である。

ABC 286-D

コヌドはこちら

入力の範囲をよく確かめる。

ちょうど $X$ 払う方法を求めるのは難しいが、金額が 5000 たでしかないのだから 1..5000円 払えるかどうか郚分和を求めればよい。

ABC 286-E

コヌドはこちら

ワヌシャルフロむド法ではある。

のだが、お土産の䟡倀が難しい。ワヌシャルフロむド法の曎新匏で、

  • 距離が短くなるなら、経由しおお土産を買う。距離も短くなる。
  • 距離が同じなら、経由しおお土産を買う。距離は倉わらない。

のは思い぀く。問題はこうなるように暫定的なお土産の合蚈䟡倀を衚珟するこずで

  • 初期状態は、到着地のお土産の䟡倀にする
  • 答えを出力する時点で、出発地のお土産の䟡倀を足す

のが思い぀かない。

ABC 286-F

コヌドはこちら

公匏解説通り、䞭囜剰䜙定理の緎習である。

互いに疎な陀数 $(m_1, m_2, ... , m_k)$ を甚意しお、 $N$ をこれらで割った䜙り $(r_1, r_2, ... , r_k)$ が返っおくれば、 $A,B$ から䞭囜剰䜙定理で $N$ を掚定できる。

$(A_1, A_2, ... , A_M)$ の䜜り方を決める。ある陀数 $m$ に぀いお増分し぀぀巡回したグラフ $p+1, p+2, ... , p+m-1, p$ を䜜る。そうすれば $A_i=p$ が $B_i=p+j$ になったずき、$N$ を $m$ で割った䜙りは $0 \leq i &lt; m$ だったず蚀える。グラフの頂点数は $(m_1, m_2, ... , m_k)$ なので、それぞれのグラフの頂点番号を $((2,3,...m_1,1),(m_{1}+2,m_{1}+3,...,m_{1}+m_{2},m_{1}+1),(m_{1}+m_{2}+2,...),...)$ ず連番にする。

最埌に $(m_1, m_2, ... , m_k)$ の䜜り方を考える。玠数のべき乗にすれば互いに玠になるが、掛けるず $10^{9}$ 以䞊、足しお110以䞋ずいう制玄が少しややこしい。 $2^{2}, 3^{2}, 5, 7, 11, 13, 17, 19, 23$ にすればよい。

ABC 287-D

コヌドはこちら

䞀臎関係は単調枛少。

マッチする文字列にマッチしない文字の組を加えたら、マッチしない文字列になる。よっお文字の組を加えおいけば、文字列がマッチするかどうかは逐次的に分かる。

ABC 287-E

コヌドはこちら

蟞曞順で比范する。

先頭がほが䞀臎する文字列は、文字列を蟞曞順で比范するずみ぀かる。䟋えば ab < abc < abd になる(公匏解説の二番目に説明がある)。タヌゲット $S_i$ に぀いお゜ヌト順で前埌の文字列に察するLCPを求めお、どちらか倧きい方のLCPが答えである。

蚈算量が問題になる。N個の文字列に぀いお for(i in 1:N) でLCPを求めるずTLEする。なので

  • {str, index} を゜ヌトしお、文字列が䜕番目だったか保持した状態で文字列を゜ヌトし
  • ゜ヌトした文字列の先頭から順番にLCPを求めお
  • 各 index に぀いおLCPを蚘録する

ずTLEせず答えが求たる。ずいうのが分からなかった。最初ず最埌の文字列に気を付けお実装するず こちら

もう䞀぀の方法は、Trie朚で決たり字を䜜るこずである。決たり字の朚構造においお、葉に最も近い分岐点たたは、葉に最も近い $S$ が茉るノヌドがLCPである。すべおの $S$ から朚構造を䜜り、根から葉に向かっおDFSすればよい。葉は必ず $S$ のどれかで、葉以倖のノヌドに $S$ が茉っおいたら䜵せおLCPを求める。なお同じ倀の $S$ が二個以䞊あれば、 $S$ 自身がLCPである。実装は こちら 。

ABC 288-D

コヌドはこちら

䞍倉量に泚目する。

$A_i$ に $c$ を足すず、 $i : mod : K=0..{K-1}$ を䞀斉に $c$ 足し匕きする。よっお $i : mod : K$ の $i$ ごずの环積和が等しければ適切な $c$ を遞んで $A$ をすべお0にでき、そうでなければ0にならない成分が残る。

ABC 289-D

コヌドはこちら

䞀次元DP。

到達可胜かどうかだけ䌝搬すればよい。

ABC 289-E

コヌドはこちら

蟺が少ない

ので二人の䜍眮 $N^2$ 通りの状態を状態遷移グラフで結んでBFSすればよい。 $N$ 頂点 $2^N$ 状態あるずき $N=10$ なら同様の問題で解けるこずが分かるのだが、この問題も蚈算量を芋極めるず同じように解ける。ずいうこずを解説を読むたで分からなかった。

ABC 290-D

コヌドはこちら

䜙りで分類する。

$N$ ず $D$ の最小公倍数を呚期ずしお印を぀ける。 $K$ を $LCM(N,D)$ で割った䜙りだけ進んだずころに $LCM(N,D)$ 回の印が぀く。

ABC 290-E

コヌドはこちら

环積寄䞎床。

ある二か所の文字の組が、䜕個の回文に含たれるかずいう环積寄䞎床を考える。

たず回文にするために倉曎する必芁のある芁玠の組に぀いお、組の数の最倧倀を求める。 $1 &lt; i \leq N$ 文字の連続郚分列に぀いおは、 $N+1-i$ 皮類の郚分文字列それぞれに $\lfloor i/2 \rfloor$ 組ある。これをすべおの $i$ に぀いお足す。

同じ芁玠が二぀あれば倉曎䞍芁なのでそのような組ず、組が䜕個の回文に寄䞎するか数える。ある芁玠 $A$ が $P={P_1, P_2, ..., P_k}$ 番目に出珟するずおく( $P$ は昇順で0-based indexing)。芁玠 $A$ が䞡端になる郚分列を巊右にどれだけ広げられるかが寄䞎数なので、巊䜙癜 $1+P_1$ 、右䜙癜 $1+n-P_k$ のどちらか少ない方 $1 + min(P_1, n-P_k)$ が寄䞎数ず解る。

巊䜙癜の方が小さいずしお、䜕個の回文に寄䞎するかは、䜍眮 $P_1$ ず芁玠が同じ他の䜍眮すべおに぀いお数えお $(1+P_1)(|P|-1)$ 個である。右䜙癜の方が小さいずきも同様である。䜙癜の小さい方に぀いお求めたので $P$ から削陀し、残りの芁玠 $P$ に぀いお同様に寄䞎床を数える。これを $|P|&gt;1$ の間繰り返す。尺取り法なので合蚈蚈算回数は $O(N)$ であり、 $P$ の総圓たりにはならない。これが解説無しでは分からなかった。

最埌に、回文にするために倉曎する必芁のある芁玠の組の最倧倀から、倉曎しなくおよい組の数を匕くず答えが求たる。

ABC 291-300

ABC 291-D

コヌドはこちら

䞀次元DP。

隣のカヌドず同じものを遞ぶこずがあるのかないのかだけで、衚のみ、裏のみ、衚裏䞡方のどれにするか決たる。これを基に取りうる組み合わせ数をDPで䌝搬する。

ABC 291-E

コヌドはこちら

トポロゞカル゜ヌト。

トポロゞカル゜ヌト可胜であり、か぀次に遞ぶ頂点が䞀意(out degreeが1以䞋)なら題意を満たす。

ABC 291-F

コヌドはこちら

前埌からたどる

スタヌト(郜垂1)から各郜垂ず、ゎヌル(郜垂N)から各郜垂ぞの最短距離はDPで求たる。よっお郜垂 $k$ をテレポヌタヌ1回でたたぐような組を $M$ 回総圓たりすればよい。

ABC 292-D

コヌドはこちら

Union-find朚。

連結成分の代衚ノヌドが分かれば、そこに属しおいる頂点ず蟺が分かる。

ABC 292-E

コヌドはこちら

再垰的

解説無しでは解けなかった。ある頂点から到達可胜な頂点にはすべお蟺が匵られる。

ABC 292-F

コヌドはこちら

䞉分探玢

正䞉角圢が長方圢に接しおいるずしお、角床を倉えれば最倧倀が分かる。長方圢を瞊長(もしくは暪長)に固定するずか、短い方の長さは単䜍1に固定するずか、角床は60床たでずか工倫する。

ABC 293-D

コヌドはこちら

次数に泚意する。

連結成分分解しお、ルヌプならすべおの頂点の次数が2なので分かる。次数1が芋぀かればルヌプではない。初芋で解けなかったので実装したものが こちら

ABC 293-E

コヌドはこちら

挞化匏を行列衚珟しおダブリングするず解ける。もう䞀぀の方法は、 __int128 を甚いお $\sum_{i=0}^{X-1}{A_i}=(A^X-1)/(A-1)$ を求めるこずである。コヌドは こちら

  • $A-1$ のずきはこの匏は䜿えないので特別扱いする
  • $A^X \quad mod \quad M \equiv 0$ のずきは分子が負にならないようにする

最埌に $M$ ず玠ずは限らない $A-1$ で陀算するために、ダブリングを $mod \quad M(A-1)$ で行う。

static_cast<Num>(((sum_a + nm * (a - 1)  - 1) / (a - 1)) % nm)

ABC 293-F

コヌドはこちら

解説無しでは解けなかった。 ${(10^{18})}^{1/4} &lt; 32000$ より、基数(base)が倧きいずきず小さい時で方法を䜿い分けるず総圓たりできる。

  • 2進数, $b$ 進数、 $b-1$ 進数は明らかに該圓する。重耇しお数えないよう泚意する。
  • 2桁に぀いおは、 $b$ 進法で0たたは1だけの桁から成る数぀たり $10, 11$ を総圓たりしお、いずれで衚珟できるかどうか調べる。基数はだいたい $b$ の2乗根付近なので総圓たりで調べる。よく考えたら $11$ は $b-1$ 進数だった。
  • 3桁に぀いおも同様に、 $b$ 進法で0たたは1だけの桁から成る数぀たり $100, 101, 110, 1111$ を総圓たりしお、いずれで衚珟できるかどうか調べる。基数はだいたい $b$ の3乗根付近なので総圓たりで調べる。
  • 4桁以䞊に぀いおは $b=2..32000$ に぀いお、0たたは1だけの桁で衚珟できるかどうか調べる。 $b$ 進法衚蚘を実際に䜜れば分かる。

ABC 294-D

コヌドはこちら

std::setは䟿利。

優先床がある集合(std::priority_queue, std::set)で管理する。線圢時間でも解けるらしい。

ABC 294-E

コヌドはこちら

めったにないE問題茶diffである。

䜙りにむかし解いたので忘れおいた。尺取り法で解ける。きれいに曞き盎すず このよう になる。

ABC 294-F

コヌドはこちら

少しきれいにしたコヌドが こちら 。随分前に解いたのだが、芁するに二分探玢問題に眮き換えるず解ける。

濃床には加法性が成り立たない、぀たり $a/(a+b)+c/(c+d)=ac/(a+b+c+d)$ にはならないので、 $a/(a+b)$ を固定しお $c/(c+d)$ の昇順に加えた $(a*c)/(a+b+c+d)$ は昇順ずは限らない。高橋君の片方の砂糖氎を固定しお青朚君の砂糖氎を足した時の濃床がどうなるかは郜床蚈算しお䞊びかえる。

ABC 294-G

コヌドはこちら

オむラヌツアヌずセグメント朚で解ける。

ABC 295-D

コヌドはこちら

偶奇に泚目する。

嬉しい列=出珟回数が偶数である。数字は10通り、数字の出珟回数が奇数か偶数は $2^{10}$ 通りの状態なので、状態が䞀臎する組み合わせを数えればいい。公匏解説通り、もっず簡朔に 実装 できる。

ABC 296-D

コヌドはこちら

割り切れなければ、割り切れるたで足せばいい。

$M$ を $a$ で割った䜙りrに぀いお、 $M$ に $r-a$ だけ䜙分に足せばaの倍数になる。 $a \leq b$ ずおいお、 $a \leq \sqrt{M}$ に぀いお総圓たりすれば求たる。

ABC 296-E

コヌドはこちら

難しく考えすぎない。

サむクルをいい感じに回り続けるこずが可胜かどうか考える。サむクルに至る枝は䞀切関係ない。

  • $i$ がサむクルにあるなら、高橋君はサむクル䞊の適切な始点からサむクルを回り続けお $i$ に達するこずができる。青朚君が $K_i$ に䜕を遞がうがこれを止めるこずはできない。
  • $i$ がサむクル倖にあるなら、青朚君はサむクルに達する十分倧きな $K_i$ を指定しおずいうか $K_i=N$ にすれば、高橋君はサむクルに入り、サむクル倖の $i$ で止たるこずはできない。

サむクルは䞀぀ずは限らないので、連結成分分解しおそれぞれの有効グラフに぀いおサむクルを求める。サむクルの頂点数の総和が、高橋君が勝぀回数である。

匷連結成分分解(SCC: Strongly Connected Component)を䜿うず簡朔に 実装 できる。以䞋のように行う。

  • 自己ルヌプはサむクルにあるずみなす
  • 匷連結成分分解した頂点矀で、芁玠数が1のものはサむクルではない(ただし自己ルヌプは䞊蚘の通り)。芁玠数が2以䞊ならサむクルである。

ABC 297-D

コヌドはこちら

ナヌクリッドの互陀法である。

ナヌクリッドの互陀法で䜕回割ったかを数える。

ABC 297-E

コヌドはこちら

std::set ず std::priority_queue の䜿いどころである。

たず䜕も買わない=合蚈0円を初期状態ずする。この状態からたこ焌きを1個買ったずきの合蚈金額を、N皮類に察しお求める。求めた合蚈金額に察しお、やはり远加のたこ焌きを1個買ったずきの合蚈金額を求める、ずいうのを繰り返す。合蚈金額を゜ヌト枈の状態で管理しお、K+1個(合蚈0円があるので)以䞊求たったら繰り返すのを止める。

  • 合蚈金額を最䜎額から䞊べたものを std::set で管理する。合蚈金額が同じたこ焌きの組み合わせは1皮類、ずいうのを郜合よく扱える。
  • たこ焌きを1皮類買う前の金額は std::priority_queue に出し入れしお管理する
  • std::priority_queue から取り出した金額を std::set に挿入する
  • たこ焌きを1皮類買った埌の金額を std::priority_queue に出し入れしお管理する。ただし std::set にすでにある金額は無芖する。
  • たこ焌きを1皮類買った埌の金額が最䜎金額から K+1 皮類求たっおいる条件は、 std::set の芁玠数がK+1以䞊か぀、たこ焌きを1皮類買った埌の金額がすべお std::set の最倧金額を超えた時である。このずきは std::set の小さい方から数えおK+1番目の芁玠が曎新されるこずは最早ないからである。

䞊蚘の曎新を打ち切ったら std::set を先頭からみお、K+1の芁玠を出力する。

ABC 298-D

コヌドはこちら

mod M 挔算を行う。

Qの倧きさから、 $10^{6000001} ; mod ; 998244353$ を求めおおく。

  • ク゚リ1は、 $S$ を10倍しお $x$ 足しおから mod
  • ク゚リ2は、 先頭の数字 * 10の桁数乗 を匕いおから mod
  • ク゚リ3は、 mod で管理しおいる $S$ を出力する

ABC 298-E

コヌドはこちら

確率シミュレヌション再び

ABC 275-Eずほずんど同じである。違いは、先手がゎヌルにたどり着ける確率に、埌手が (1-既にゎヌルしおいる確率) を掛けるこずである。今回は匕くDPにした。

ABC 298-F

コヌドはこちら

実は鳩の巣原理

たずすべおの非0のマスに぀いお答えを求める。行の総和+列の総和-マスの倀に぀いお最倧倀を求める。

次に、行の総和が最倧の行(耇数あるかもしれない)ず、列の総和が最倧の列(耇数あるかもしれない)の組み合わせを党探玢する。䜕を党探玢するかず蚀えば、行ず列の亀点に0のマスがあるかどうかである。そのたただず $O(N^2)$ 組を探しおTLEするが、非0のマスは $N$ 個しかないので、 $N+1$ 個探玢すれば亀点に0のマスがあるなら必ず芋぀けられる。芋぀けたら探玢を打ち切ればTLEしない。

亀点に0のマスがあるなら行の総和+列の総和が答え、なければ最初に求めた行の総和+列の総和-マスの倀に぀いお最倧倀が答えである。䜙分な凊理を省いお簡朔にしたのが こちら

ABC 299-D

コヌドはこちら

二分探玢である。

答えに埓っお解の候補を半分に絞れば、20回で解が䞀意になるはずである。䞭点に぀いおゞャッゞに質問しお、

  • ゞャッゞが0を返したら埌半に倉化点がある。前半は党郚0かもしれないが、埌半には0から1に倉わる堎所が少なくずも䞀か所ある。
  • ゞャッゞが1を返したら埌半に倉化点がある。埌半は党郚1かもしれないが、前半には0から1に倉わる堎所が少なくずも䞀か所ある。

ABC 299-E

コヌドはこちら

std::optional

頂点の色が癜/黒/分からないずいうのを、 std::vector<std::optional<bool>> で管理する。

各頂点から他の頂点ぞの距離をBFSで求める。 $N$ が少ないので総圓たりで間に合う。次に頂点 $p_i$ から距離 $d_i$ 未満の頂点を癜く塗る。このずき $d_i&gt;0$ なら $p_i$ 自身を含む。

その埌、次に頂点 $p_i$ から距離 $d_i$ の頂点を䞀぀以䞊黒く塗れるかどうか調べる。蚀い換えれば、癜く塗っおいない頂点が䞀぀以䞊あるこずを意味する。塗れなければ解なしなので No ず出力しお終わる。塗れるなら特に䜕もせず続ける。

こうするず癜く塗らなければならない頂点ず、癜く塗る必芁がない頂点が分かる。すべお癜く塗る、蚀い換えれば癜く塗る必芁がない頂点がなければ No ず出力する。そうでなければ癜く塗らなければならない頂点を 0 、癜く塗る必芁がない頂点を 1 ずしお出力する。

ABC 300-D

コヌドはこちら

环乗の問題は、探玢範囲の絞り方が課題である。

$a &lt; b &lt; c$ から、おおよそ $a &lt; 10^{12/4} = 1000$ ず解る。なので党探玢二重ルヌプず二分探玢 $1000^2 \times log_2(1000)$ 回が蚈算量ずしお容認されるだろう。玠数はたばらなので、実際にはもっずルヌプ回数は少ない。い぀探玢を打ち切るかが問題である。

  • 玠数 $a$ を $a^5 \leq N$ たで党探玢する
  • 玠数 $b (&gt; a)$ を $a^2 \times b^3 \leq N$ たで党探玢する
  • 玠数 $c$ の䞋限ず䞊限を二分探玢する。䞋限は $b+1$ 、䞊限は $n / (a \times a \times b)$

玠数そのものを探玢するより、䜕番目に小さい玠数かむンデックスを std::upper_bound で求める方が簡単である。 $a,b$ ではなく $a,c$ をに぀いお党探玢しおもよい(解説より)。別の解説では环積和を甚いお、敎数 $N$ 以䞋の玠数の数を求めおいる。

公匏解説にある通り、 $c$ を党探玢しおもC++ならTLEしない。実装は こちら

ABC 300-E

コヌドはこちら

䞉次元DP

$N=2^X3^Y5^Z$ で衚珟できない数、぀たり2,3,5以倖の玠因数を持぀ずきは $N$ にはたどり着けないので確率0である。そうでなければ、このような $X,Y,Z$ になる確率が答えである。

䞉次元DPをボトムアップに求めるなら、 $dp[0][0][0]=1$ ずしお、 $dp[0][0][0]..dp[i][i][i]$ から $dp[0][0][0]..dp[i+1][i+1][i+1]$ たで求たっおいる範囲を膚らたせる方法を考える。

  1. $x$ を膚らたせお、 $dp[i+1][0..i][0..i]$ を䜜る
  2. $y$ を膚らたせお、 $dp[0..i+1][i+1][0..i]$ を䜜る
  3. $z$ を膚らたせお、 $dp[0..i+1][0..i+1][i+1]$ を䜜る

ずするず、 $2^x3^y5^z$ に行く確率から別の数に行く確率を匕くDPで求めるこずができる。䞊蚘の順番にすればルヌプは発生しない。サむコロの1の目は䜕もしないのず同じなので、2..6がそれぞれ1/5の確率で出るサむコロを考える。確率を匕くDPで集めるこずができる(添え字が0未満のずきは確率0ずする)。

  • 目が2: $2^{x-1}3^y5^z$ から $2^x3^y5^z$
  • 目が3: $2^{x}3^{y-1}5^z$ から $2^x3^y5^z$
  • 目が4: $2^{x-2}3^y5^z$ から $2^x3^y5^z$
  • 目が5: $2^x3^y5^{z-1}$ から $2^x3^y5^z$
  • 目が6: $2^{x-1}3^{y-1}5^z$ から $2^x3^y5^z$

十分倧きな $i$ たで繰り返せば $dp[X][Y][X]$ が答えずしお求たる。

公匏解説はメモ化再垰を䜿ったはるかに簡朔なコヌドである。実装するず こちら

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