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

AtCoder Beginner Contest lessons learned (ABC 201-250)

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

トップペヌゞぞ

ABC 201-210

ABC 201-D

コヌドはこちら

ゲヌム理論ずミニマックス法である。

2人の埗点差だけに意味がある。埗点差が正なら先手の勝ち、埗点差が負なら埌手の勝ち、埗点差が0なら匕き分けず定矩する。マスに移動したずきの埗点を、

  • 先手なら玠盎にマスの埗点(+1なら+1, -1なら-1)
  • 埌手なら先手が劂䜕に損するか、ず読み替えお正負を入れ替える(+1なら-1, -1なら+1)

ずしお、先手は埗点差を最倧化、埌手は埗点差を最小化するように移動すればよい。

盀面の倖にはみ出さないようにするのだが、マスから䞀手移動する先をキュヌで管理するずTLEするので、ゎヌルたで(たたはスタヌトから)距離が $i$ なマスをforルヌプで求める。慣れおないずこの凊理が意倖ず倧倉である。

ABC 201-E

コヌドはこちら

朚DPかず思ったらそうではなかったので諊めた。

XOR距離を取るずきに、根からLCAたでは埀埩するので0になるこずが芋抜けなかった。そうず分かれば、それぞれのビットを独立に考えお、0ず1の組がいく぀か数えればわかる。

ABC 202-D

コヌドはこちら

䞊の桁から順番に決めおいく。

  • 未決定の桁のうち、最䞊䜍桁をaをしお残りの組み合わせがk以䞋なら、最䞊䜍桁をaをしお残りの桁を決める
  • そうでなければ最䞊䜍桁をbにしお、kから残りの桁が取りうる組み合わせを匕いおあら、残りの桁を決める
  • aずbのどちらか䞀方が残っおいなければ、残りはbだけたたはaだけに決たる

aずbの組は $2^{a+b}$ なので、組み合わせの数は 32-bit intでは収たらないが64-bit intには収たる。

ABC 202-E

コヌドはこちら

オむラヌツアヌである。

æ ¹1からDFSでオむラヌツアヌをする。探玢で蚪れた頂点の順番 $i=1..$ に察しお、頂点 $v$ を最初に蚪れた時の順番を $L[v] = i$ 、頂点 $v$ を最埌に蚪れた時の順番を $R[v] = i$ ずする。頂点 $v$ をDFSで呌び出すずき(戻るずきではない)は、深さを $d$をずしお、頂点 $U$ の深さを $W[v] = d$ 、深さ $d$ ずなる探玢順序の集合 $S[d]$ に $v$ を加える。

ク゚リ $(U,D)$ を以䞋の通り凊理する。

  • $D = 0$ のずき、 $U = 1$ なら答えは1、そうでなければ答えは0である
  • $D > 0$ のずき、 $W[U] < D$ なら答えは0、 $W[U] = D$ なら答えは1、そうでなければ䞋蚘を怜蚎する。

頂点 $U$ の郚分朚は、オむラヌツアヌの探玢順序 $[L,R]$ に含たれる頂点のうち、深さ $D$ のものである。これは $S[D]$ を $L,R$ で二分探玢するこずで、間にある頂点数が分かる。これがク゚リの答えである。

ABC 203-D

コヌドはこちら

答えが敎数 $n$ ちょうどであるこずを確認するのは倧倉だが、答えが $n$ 以䞊たたは以䞋であるこずを確認するのは容易である。

䞭倮倀を求めるのではなく、䞭倮倀 $median$ を決め打ちする。䞭倮倀を決める順䜍の定矩 $rank = \lfloor k^2/2 + 1 \rfloor$ より、

  1. すべおの池で䞭倮倀を超える芁玠数が $rank$ 以䞊なら䞭倮倀を䞊げられる
  2. いずれかの池で䞭倮倀を超える芁玠数が $rank - 1$ 以䞋なら䞭倮倀を䞋げられる

ず $left-right$ 間を二分探玢する。䞭倮倀を超える芁玠数を池ごずに数えるのは、二次元环積和でできる(环積和の逆算が池の芁玠数)。境界条件がややこしいが、境界条件 $left+1=right$ ではrightが二番目を満たす最䜎倀であり、求める答えである。

ABC 203-E

コヌドはこちら

ポヌンが無い行は䜕も起きず、1個のポヌンで到達可胜な列は高々2列しか増えないので、蚈算量は $O(M)$ が基本ず芋積もれる。

到達可胜な列の集合を $S$ ずする。ポヌンが無い行の昇順に぀いお、各行に぀いお到達可胜な列を曎新する。ある行に眮かれたポヌンの列番号の集合を $T, |T| > 0$ ずする。

  • $S$ から $T$ を陀く
  • $S$ に $(v-1, v+1) : v \in T$ を加える

最終的な $|S|$ が答えである。蚈算量は $O(Mlog(M))$ である。

ABC 204-D

コヌドはこちら

倀域から蚈算量が少ないこずが読み取れる。

$T_i$ が1000通り、 $N$ が100なので、 $T_i$ の和は10䞇通りしかない。よっおオヌブンを䜿う時間ずしお10䞇通りがありうるか吊かを蚈算すればよい。 $sum(T_{1..N})/2$ 以䞊の最も近い和が答えである。

ABC 204-E

コヌドはこちら

匏導出ができずに諊めた。解説通り実装した。

時間を぀ぶす堎所はどこでもいいので出発点のみで時間を぀ぶせばよい、ずいう考察は間違っおいる。

ABC 205-D

コヌドはこちら。もっず簡朔に実装できる。

$K_i$​ がAに含たれるなら、Aに含たれない数たで滑っおいくず考える。 $A_j$ 以䞋でAに含たれない敎数の数は、Aを昇順に䞊べ替えおスキャンするず分かるので、これを二分探玢すればよい。

ABC 206-D

コヌドはこちら

Union-find朚は掚移関係を衚珟できる。

AをBに眮き換え、BをCに眮き換えれば、AはCになるずいう掚移則が成り立぀。なのでAからB、BからCに眮き換えるず分かっおいるなら、AからCたたはCからAぞの眮き換えは芁らない。これをunion-find朚で管理する。答えはunion-find朚に远加した回数である。

ABC 206-E

コヌドはこちら

玄数包陀原理だずは分かったがどうしおも答えが合わないので諊めた。

$g = GCD$ を固定しお総圓たりする。重芁なのはstep2である。 $L \leq g \leq R$ のずきに、 $x = g$ で $y$ が $g$ の倍数、 $y = g$ で $x$ が $g$ の倍数、 $x = y = g$ の堎合を数え䞊げるず、 $2 \lfloor R/g \rfloor - 1$ 個である。ここたでくれば、 $g$ の倍数であっお $kg$ の倍数で無い数を数え䞊げる。

ABC 207-D

コヌドはこちら

この皮の数孊問題は正解率が䜎いので、獲れるず差が぀く。

重心で回転すれば、二぀の図圢が䞀臎するならすべおの点が重なる。䞀方を固定すれば、回転角は点の数だけしかない。原点からの距離が䞀臎する点を芋぀けお(芋぀からないなら二぀の図圢が䞀臎しない)角床をそろえ、すべおの点の座暙が䞀臎するかをどうかを䞀通りの回転角で詊しおみる。

すべおの点の座暙が䞀臎するかどうかを総圓たりで蚈算しおよいのである。我ながら惜しかった。

ABC 207-E

先頭から $L \in 1..N$ 個の芁玠を䜿っお、最埌に $D \in 1..N$ の区間を求めたずする。区間 $[L+1,R]$ が $d + 1$ の倍数ずなるような $R$ を求めればよい。これは $\sum_{L+1}^R mod D$ が0であり、あらかじめ环積和を取るこずで、 $cumsum(L) \equiv cumsum(R) mod D$ ず蚀い換えらえる。

先頭から $L \in 1..N$ 個の芁玠を䜿っお、最埌に $D \in 1..N$ の区間を求める方法が $DP[L,D]$ 通りであるこずをメモ化するず、メモ化再垰で解ける。はずなのだがどうしおも1 TLEが取れない。他の方の実行速床を芋る限り、蚈算量が萜ちおいない。

ABC 208-D

コヌドはこちら

頂点数が少ないグラフには、ワヌシャルフロむド法が䜿える。

ワヌシャルフロむド法のルヌプは倖から順に、経由地、出発地、到着地にする。この順番を間違えるず解けない。

ワヌシャルフロむド法は、経由地の番号が浅い順に最短距離が曎新される。この途䞭結果を集蚈すれば、問題の答えが求たる。

ABC 209-D

コヌドはこちら

二点間の距離は、䜙分に埀埩しおも蚈算結果が倉わらないこずがある。

䟋えばオむラヌツアヌは、行きを枝の重み $w$ 、垰りを $-w$ にすれば䜙分な経路は足し匕き0にできお二点間の最短距離(共通の祖先で折り返す)が求たる。

この問題では、䞀埀埩するず距離は偶数増えるので、最短距離か寄り道したかで、二点間の距離の偶奇は倉わらない。なので二点間の移動は必ず根を経由するこずにしお、根からの距離の和にしおも、二点間の距離の偶奇は倉わらない。距離が偶数なら街で、奇数なら道路䞊で出䌚う。

ABC 210-D

コヌドはこちら

盀面を回転すれば絶察倀を倖せる。

ずいうこずで、盀面を4回回転しお、巊䞊の駅の方が高いずいう仮定の䞋で求める。DPを䞊手く䜿う。なんずなく解るずいうだけでは実装できないので、よく理解する必芁がある。

ABC 210-E

コヌドはこちら

MSTならクラスカル法ずいうのが盎球すぎおわからなかった。連結成分の数がGCDだずいうのはなんずなく察しお、互いに玠な $A$ を連結しようずしたが䞊手く解法に぀ながらなかった。

ABC 211-220

ABC 211-D

コヌドはこちら

蟺の距離が等しいのでBFSで解く。

キュヌには距離を茉せ、それずは別に頂点1から他の頂点ぞの距離ず、他の頂点に行く組み合わせを管理する。

  • 蟺をたどるず最短経路にならない頂点(迂回路の先に頂点)はキュヌに茉せない
  • 蟺をたどるず最短経路以䞋になる頂点に぀いおは、その頂点に行く方法の数を足す
  • ぀たり蟺の先の頂点が最短経路ちょうどのずき、蟺の先の頂点をキュヌに茉せないが、その頂点に行く方法の数を足す。これがこの問題の肝である。

鉄則本の力詊し問題 C14の芁領で解いたら、ダむクストラ法なので $O(N*log(N))$ 解法だったために 1791 ms のTLEぎりぎりだった。ここでは蟺の長さは固定なのでBFSでよく、過去問の知識を手盎しせずそのたた䜿っおはいけない。

ABC 211-E

コヌドはこちら

$K$ が小さいので、重耇ありの党探玢が通る。

最初の点 $(Y,X)$ を $N^2$ 通り決め打ちしお、これたで加えた点に隣接する癜マスを加えお、 $K$ マスになったらその赀マスを蚘録する。重耇を避けるために、始点より $Y + 8X$ が小さい点は探玢しない。これたで加えた点を std::set<Num> 、赀マスを std::bitset<64> で持぀ずTLEしない。 std::unordered_set<Num> を䜿っおも倉わらない。

䞀筆曞きできるずは限らないので泚意する。

ABC 212-D

コヌドはこちら

䞋駄を履かせる。

倉数に䞀斉に同じ数を足す操䜜は、足した倀をオフセットずしお持おば、それぞれの倉数を曎新しなくお枈む。オフセットの初期倀は0である。

ABC 212-E

コヌドはこちら

制玄をよく芋る。

行列挔算のコストが高すぎおダブリングは䜿えない。よっお別の方法を探す。 $M \leq 5000$ なので、ずりあえず道が぀ながっおいるものずしお組み合わせ蚈算し、぀ながっおいない道の分だけ組み合わせを匕けばよい。

道の遷移行列を盎に掛けるず $O(N^3)$ になるので、぀ながっおいない道の分だけ蚈算するず $O(N^2)$ になる。自己ルヌプも぀ながっおいない道ずしお加えおおく。

ABC 213-D

コヌドはこちら

蟺の数が頂点の数-1で、すべお頂点が連結なら朚である。

蟺を std::vector<std::vector<Num>> で管理するず、頂点から次にたどる頂点を䞊べ替えできる。あずはDFSで蚪ねればいい。この方法はオむラヌツアヌなので、スニペットにしおおく。

ABC 212-E

コヌドはこちら

小さな距離ず倧きな距離

壁の無いずころに䞀歩螏み出す時の小さな距離を $1$、壁があるが壊したら行けるずころたでいく倧きな距離を $10^7$ ずする。

壁がなければ行ける堎所の、珟圚地からの盞察座暙。

std::vector<std::pair<Num, Num>> diffs_short {
    {-1, 0}, {1, 0}, {0, -1}, {0, 1}
};

壁を壊しお行ける堎所の、珟圚地からの盞察座暙。

std::vector<std::pair<Num, Num>> diffs_long {
    {-2, -1}, {-2, 0}, {-2, 1},
    {-1, -2}, {-1, -1}, {-1, 0}, {-1, 1}, {-1, 2},
    {0, -2}, {0, -1}, {0, 1}, {0, 2},
    {1, -2}, {1, -1}, {1, 0}, {1, 1}, {1, 2},
    {2, -1}, {2, 0}, {2, 1}
 };

これらをすべおのマスから盞察座暙で行った先に぀いお、双方向の枝を匵る。埌は巊䞊から右䞋たでダむクストラ法で最短距離を求め、倧きな距離で割るず答えが求たる。小さな距離はいくら長くおも答えは倉わらない。

壁を壊しお進むならそれはゎヌルに向かう最短経路なので、壊した2x2の壁の䞭には䞀床入ったらそこから出るしかなく、壊した2x2の壁の䞭を倧きな距離で動くこずはありえない。

公匏解説によれば01BFSで解けお、その方が実装が簡単で速い。

ABC 214-C

コヌドはこちら

灰diffだが、AtCoder Daily Training MEDIUM 2023/11/23 18:30 start で解いお手こずった。

時刻で高速シミュレヌションする。初期倀はすぬけ君 $i=1..N$ がそれぞれ時刻 $T_{i=1..N}$ に宝石を受け取ったずしお、 std::set 型の集合 $S$ に茉せる。 $S$ は時刻 $t$ ずすぬけ君の番号 $i$ の組 $[t,i]$ からなる。

すぬけ君 $i$ が初めお宝石をもらう時刻を $U_i$ ずしお $\infty$ で初期化する。 $S$ のうち最も時刻の早い芁玠 $t,i$ を取り出しお削陀する。 $t \leq U_i$ なら䜕もしない。 $t &lt; U_i$ なら $U_i$ を $t$ にし、 $[t+S_i,i+1]$ を $S$ に加える。 $i+1$ は $mod N$ である。キュヌから取り出すごずに、 $U_i$ が確定するすぬけ君が䞀人いるか宝石が䞀぀枛るかいずれかが成立するので、ルヌプは $O(N)$ 回、蚈算量は $O(Nlog(N))$ である。

公匏解説通り二呚させるず $O(N)$ 解法になる。実装は こちら

ABC 214-D

コヌドはこちら

蟺の重みの最倧倀に関心があるなら、その蟺より重い蟺を陀けばいい。

ずいうこずで、軜い蟺から重い蟺に向かっお順番に蟺を远加しお、最終的に朚になるようにする。蟺 $(u,v)$ を䞀本远加したずきに、その蟺によっお掚移的に連結可胜になる(互いに行き来できる)頂点は、 $u$ の連結成分(最䜎1個)ず、 $v$の連結成分(最䜎1個)ずの盞互間なので、䞡連結成分の数の積である。

連結成分はunion-find朚で管理する。蟺が無い頂点の連結成分は1個で、 atcoder::dsu::size もそうなっおいる。

ABC 215-D

コヌドはこちら

゚ラトステネスの篩っぜいこずをする。

これは公匏解説通りである。 $A_i$ の玠因数の倍数をすべお削陀枈ずいう印を぀ける。同じ玠因数は䞀床だけ行う。゚ラトステネスの篩はかなり蚈算量が小さいので、䌌たようなこずを頑匵っお実装しおも倧倉なだけである。

ABC 215-E

コヌドはこちら

N=10ならBitDP

なのだが、加算方法が4通りあっおよく堎合分けしないず解けない。

ABC 216-D

コヌドはこちら

シミュレヌションしおもいいが、しなくおも枈むこずがある。

色が $I$, $J$ 、個䜓が $I_1$, $I_2$, $J_1$, $J_2$ のボヌルがある。詰んでいる状況は以䞋の通りである。

  • 同じ筒に $I_1$, $I_2$ がある
  • $I_1$ の䞊に $J_2$ か぀ $I_2$ の䞊に $J_1$ がある (1ず2を入れ替えおも察称なので同じ)

これだけ怜出すればACできた。解を瀺せず蚀われたらトポロゞカル゜ヌトでできるらしい。

ABC 216-E

コヌドはこちら

䞊から敎地する。

楜しさが最倧のアトラクションに、楜しさが二番目になるたで乗りたくる。次に楜しさが最倧だったおよび最初は二番目のアトラクションに、楜しさが䞉番目になるたで乗りたくる。以䞋同様に楜しさを敎地しお、K回乗るかすべおのアトラクションの楜しさが0になるたで乗ればよい。このずき満足床が最倧になるので貪欲法で解ける。Kが䞭途半端に䜙ったずきの凊理に気を付ける。

別解ずしお二分探玢がある。 こう実装した。

ABC 216-F

コヌドはこちら

C配列はできれば䜿いたくない。

この問題の本質ではないのだが、C配列のサむズを䞀桁間違えたためにバッファオヌバヌランが発生しお結果がおかしくなり、ゞャッゞサヌバがREするたで気が付かなかった。できれば範囲チェック付きの配列を䜿いたい。そもそもこの問題で二次元配列は必芁ない。

本題に戻るず $(A_i, B_i)$ を $A_i$ で゜ヌトしおおけば、 $S$ の和の䞊限がいく぀かを明瀺的に管理する必芁は無くなる。䟋によっお $DP[i][v]$ ずしお $i$ は集合 $S$ に $i$ 番目たで詰めたかどうか、 $v \leq 5000$ は $S$ の倀の和である。 $DP[0][0]=1$ ずしお倖ルヌプは $i=1..N$ 、内ルヌプは $0 \leq v \leq 5000$ に぀いお解けばいい。

$i-1$ 番目たでを $S$ に詰めた ( $B_{i-1}$ を詰めたかどうかは問わない)組み合わせの数を $DP[i-1][v]$ ずする。 $B_i$ 番目を $S$ に詰めたずきに $DP[i][v+B_i] = DP[i-1][v]$ であり、 $v+B_i \leq A_i$ なら題意を満たす個数 $DP[i-1][v]$ の総数を加算する。 $B_i$ 番目を $S$ に詰めなければ $DP[i][v] = DP[i-1][v]$ であり、題意を満たす個数は増えない。

ABC 217-D

コヌドはこちら

STLの䜿いこなしが問われる。

切れ目 std::set<Num> cuts を順序付けお䞊べ、 cuts.upper_bound(x) で芋぀かる。「ク゚リを凊理する時点で切られおいないこずが保蚌されたす」ので lower_bound でよかった。

ABC 217-E

コヌドはこちら

コレクションを二぀に分ける。

この皮の問題で䜕床も芋た通り、゜ヌト枈集合ず、挿入順序が぀いた集合の二぀を分ける。゜ヌト枈集合は std::multiset でも優先床キュヌでもよい。挿入順序は std::queue だが、ク゚リ3で空にするので std::vector でもよいかもしれない。

ABC 218-C

コヌドはこちら

実際にやっおみる。

䜙癜の削陀ず回転はそこそこ長いコヌドになるので、あらかじめコヌドスニペットにしおおく。

ABC 218-D

コヌドはこちら

制玄をよく芋る。

$N$ が小さいので二重ルヌプできる。長方圢の頂点は、察角線䞊の二点を定めれば残りも求たる(x軞ずy軞に䞊行なので)。埌は総圓たりでよい。

ABC 218-E

コヌドはこちら

逆から考える。

蟺を陀くのではなく、蟺を付け足すこずを考えるず、union-find朚を掻甚できる。

報酬が負の蟺は陀く䟡倀がないので最初から存圚するこずにする。このずき蟺を増やせばい぀かは党頂点が連結になる。これは最小党域朚を構成するアルゎリズムず同じである。

  • 蟺 $(A_i, B_i)$ の $A_i, B_i$ が連結なら、連結成分は増えないので蟺を足す意味は無い。これは蟺を陀くこずの逆操䜜なので、報酬 $C_i$ をもらえる。
  • 蟺 $(A_i, B_i)$ の $A_i, B_i$ が連結でなければ、連結成分が増える。報酬はもらえない。

ABC 219-D

コヌドはこちら

繰り返しになるが、制玄をよく芋る。

たこ焌きずたい焌きはそれぞれ300個しか食べないのだから、300個以䞊は䞀埋300個ずみなしお構わない。そうすれば $A_{1..N}$ から任意の芁玠を取ったずきの和ずしお取りうる倀は、301通りしか考えなくお枈む。

ABC 220-D

コヌドはこちら

悩むより手を動かすこずもずきには倧事。

問題文の通り実際に実装するず答えが求たる。 $(10^5, 10)$ 芁玠のテヌブルを䜜っおもMLEしないので、省メモリを考えるのは時間の無駄である。

意の芁玠を取ったずきの和ずしお取りうる倀は、301通りしか考えなくお枈む。

ABC 220-E

コヌドはこちら

重耇を䞊手く数える。

$(i,j)$ ず $(j,i)$ を別に数える。これが匕っ掛かっお解けないこずがある。

題意を満たす頂点の組を数え䞊げるには、朚の高さ(根から葉たでの蟺の数)を $0..N-1$ たで増やしおいけばよい。

  • 根しかないずきは、題意を満たす頂点の組は存圚しない
  • 高さが1のずきは、葉から距離1で到達できるのは根だけ、葉から距離2で到達できるのは根の先にある葉だけである。
  • 高さが2のずきは、葉から距離1で到達できるのは葉の芪だけ、葉から距離2で到達できるのは葉の兄匟ず根、距離3以䞊だず根の向こう偎にある頂点に到達する
  • 高さが3ずきは、葉から距離1で到達できるのは葉の芪だけ、葉から距離3で到達できるのは根ず葉の間にLCA(最小共通祖先)がある頂点、距離3だず根だけで、距離4以䞊だず根の向こう偎にある頂点に到達する。

高さが2のずき葉から距離2で到達できるのは根ず葉の兄匟ずいうのは、高さ1の朚ず同じである。぀たり高さが $i$ のずきの組み合わせの数は、 高さが $1..i$ のずきの組み合わせを含むこずが分かる。より粟緻には、朚の高さが $i$ で頂点間の距離が $D$ のずき以䞋の通りになる。

$i*2 &lt; D$ ならどの二頂点をずっおも距離が $D$ を超えおしたうので、そのような頂点の組は存圚しない。

$i \geq D$ なら、ある頂点 $v$ から距離 $D$ にある頂点 $u$ は根の向こう偎にある。そのような頂点は根からの距離が $2^{i-D}$ なので、 $v$ に察応する頂点 $u$ は $max(1, 2^{i-D-1})$ 個である。根の向こう偎なので半分になるこずに泚意する。

  • $(v,u)$ の組み合わせは、 $i \ne 2D$ なら $2 |v| \times |u|$ 個である。 $v$ ず $u$ は根からの距離が異なるので区別でき、入れ替えたものも数えるために倍にする。
  • $i = 2D$ なら、 $v$ ず $u$ は察称なので $|v| \times |u|$ 個 である。 $v$ ず $u$ は根からの距離が同じで区別できず、入れ替えたものを数えないため倍にしない。ここを間違えやすい。

$i &lt; D$ なら、ある頂点 $v$ から距離 $D$ にある頂点 $u$ は根のこちら偎にある。぀たり $v$ ず $u$ のLCA(最小共通祖先)は $v$ ず 根の間にある。LCAを $v$ から近い順、぀たり $v$ ずの距離が $j=1..D$ それぞれに぀いお頂点の組み合わせの数をを求めればよい。これは高さ $j$ の朚ずしお既に求たっおいる。

高さ $j$ 以䞋の組み合わせを环積和にしおおかないずTLEする。 $v$ ず $u$ は根からの距離が異なるので区別でき、入れ替えたものも数えるために倍にする。これも忘れやすい。

ABC 220-F

コヌドはこちら

intだずオヌバヌフロヌする。

䜕か適圓な頂点を根にしお朚を䜜る。このずき各頂点に぀いお子頂点の数(自分自身は含めない)を数え、すべおの頂点の深さの和(根は0ずする)を集蚈しおおく。DFSで求たる。

根に぀いおはすべおの頂点の深さの和が答えである。根の子頂点 $i$ に移動するこずを考える。 $c$ の子頂点の数を $n_i$ ずしたずき、 $c$ および $c$ の子頂点に寄ったので距離の和は $n_i + 1$ だけ枛り、それ以倖の頂点ずの距離の和は $n - n_i + 1$ だけ増えお、合蚈で $n - 2(n_i + 1)$ 増える。これを根からDFSで再垰的に求めるず、すべおの頂点に぀いお距離の和が求たる。 $O(N)$ で求たる。

LCAの実装をそのたた䜿うず $O(N^2log(N))$ になっおTLEする。

ABC 221-230

ABC 221-D

コヌドはこちら

いもす法である。

い぀も通り出入りむベントを定矩しお、同䞀時刻を圧瞮しおから蚈算する。

ABC 221-E

コヌドはこちら

区間和を $O(log(N))$ で曎新するならセグメント朚。

$A_i \leq A_j$ か぀ $i &lt; j$ なら取りうる組み合わせは $A_i$ で始たり $A_j$ で終わる $2^{j-i-1}$ 通りである。これを $i=1..N$ ず $j=(i+1)..N$ に぀いお取れば答えが求たる。のだが、このたたでは $O(N^2)$ なので䞀工倫芁る。

セグメント朚に茉せるず䞊手くいく。たず入力を座暙圧瞮する。 $(A_i, i)$ を蟞曞順に䞊べ替えるず、 $A$ が小さい順、 $A$ が等しければ $i$ が小さい順に䞊ぶ。この順序 $ord(i)$ を圧瞮埌の座暙ずしお、セグメント朚の添え字にする。次に $A_1$ の解ずしお、セグメント朚の添え字 $ord(i)$ の倀を $2^{i-2}$ にする。

$A_1 \leq A_j : 1 &lt; j$ になる組み合わせの数に぀いおは、 $[ord(1), N]$ に぀いおセグメント朚の倀を足せば答えが求たる。ずいうのはそのようにセグメント朚の倀を蚭定したからである。 $A_2$ に぀いお求める前に、セグメント朚の添え字 $ord(i)$ の倀を0にしお、以埌 $A_1$ ずの組み合わせは考慮しないようにする。

$A_2 \leq A_j : 2 &lt; j$ になる組み合わせの数に぀いおは、 $[ord(2), N]$ に぀いおセグメント朚の倀を足せば答えが求たるがこれは $A_1$ ず $A_j$ ずの距離を反映した2倍の倀なので半分にする。このあずセグメント朚の $ord(2)$ の倀を0にしお、以埌 $A_2$ ずの組み合わせは考慮しないようにする。

䞀般的に $A_i \leq A_j : i &lt; j$ になる組み合わせの数に぀いおは、 $[ord(i), N]$ に぀いおセグメント朚の倀を足しお $2^{i-1}$ 割ったものが答えである。 $ord(i) = 0$ なら0通りである。これを $i=1..N$ に぀いお求めお足せば $O(Nlog(N))$ で答えが求たる。

ABC 222-D

コヌドはこちら

制玄をよく芋るず、倀域が狭い。

基本は数列の $i$ 番目たでみお、 $C_i=J$ なら $dp[i][j]$ 通りである。 $dp[i][j]$ を匕っ匵っおくる元は、最も広い区間で $dp[i-1][a_{i-1}..b_{i-1}]$ なので、jに぀いお环積和を取らないずTLEする。

ABC 222-E

コヌドはこちら

久しぶりに連立方皋匏。

ある頂点から他の頂点に行く経路は、BFSで経路を蚘録しながら求たる。よっおある蟺を䜕回通るかも分かる。

1回以䞊通る蟺が $p$ 本あるなら $dp[i][j]$ すればよい。 $i=0..p$ 番目の蟺に぀いお、赀く塗られた蟺を $j$ 回通った回数を逐次的に求めればよい。䞀回も通らない蟺が $q$ 本あるなら䜕色で塗っおもいいので、組み合わせの数を $2^q$ 倍する。始終点の頂点が垞に等しい堎合は $p=0$ なので泚意する。

Rが0通りの堎合があるのに泚意する。 $R - B = K$, $R + B = p$ より $R \times 2 = K+p$ なので、 $K+p&lt;0$ たたは $K+p$ が奇数ならRは0通りである。

ABC 223-D

コヌドはこちら

A happens before B ずいう条件は有効グラフで衚珟できる。

すべおの条件をを満たす解があるなら、トポロゞカル゜ヌトで解を埗られる。トポロゞカル゜ヌトに䞀意性はないが、優先床キュヌを䜿うずできるだけ頂点番号が最小のものから䞊べた解が埗られる。

トポロゞカル゜ヌト可胜ず埪環(サむクル)が無いこずは同倀である。トポロゞカル゜ヌト埌の頂点数が入力より少なければ、トポロゞカル゜ヌトできなかった、぀たりサむクルがあったず分かる。

ABC 223-E

コヌドはこちら

考察が倧倉。

長方圢が2個なら、指定された面積以䞊なのだから暪幅䞀杯広げお、その䞊に他の長方圢を乗っければよい。瞊暪は亀換しお詊す。

長方圢が3個なら、たず䞋に䞀個眮いお残り2個をを䞊に眮けばいい。瞊に積むか暪に積むかはそれぞれ詊す。瞊暪は亀換しお詊す。

$A,B,C$ の順列、䞊び替え埌の $A,B$ に察しお $A$ を瞊眮きか暪眮きか ($X,Y$ を入れ替えればいい)、 $B$ を瞊眮きか暪眮きか、ずいう24通りを総圓たりすればよい。実装は こちら

ABC 223-F

コヌドはこちら

遅延セグメント朚。

( ず ) を +1 ず -1 に読み替えお、括匧の収支が合えばいい。぀たり区間 $[L,R]$ の区間和が0で、郚分区間和 $[L,L..R]$ の最小倀が0以䞊であればいい。

区間和はセグメント朚で管理し、ク゚リ1でセグメント朚のノヌドを入れ替える。これずは区間和の最小倀を遅延セグメント朚で管理する。

  • ノヌドは敎数ずする
  • 区間に察するク゚リは、区間の最小倀を返す。単䜍元は負の無限倧にする。
  • ノヌドに察する䜜甚玠は敎数の可算にする

ノヌド $L,R$ を入れ替えるず、先頭からの区間和぀たり环積和 $cumsum$ は $S[L,R)$ を入れ替える前の $S[R]-S[L]$ だけ増える。これは遅延セグメント朚にうっお぀けである。これ以倖の区間は増えない。 $S[R,N]$ は倉わらないが、境界を䞀぀間違えやすいの泚意する。

ク゚リ2に察しおは、 $S[L,R)$ の区間和が0で、 $S[L,R)$ の区間和の最小倀が0以䞊぀たり $cumsum[L-1]$ 以䞊なら正しい括匧列である。䟿宜䞊 $cumsum[0] = 0$ ずする。区間曎新䞀点取埗できるデヌタ構造なら遅延セグメント朚でなくおもよい。

ABC 224-D

コヌドはこちら

状態遷移はグラフで衚珟できる。

この皮のパズルは、コマではなく空癜を動かすず考える。すべおのコマの状態を遷移前ず遷移埌を蟺で結び、状態間の最小距離が答えだ。よっおBFSで求たる。C++で1秒掛かる。

空癜を 9 する。 123456789 をゎヌルずしお、 123456789 から 987654321 たでの順列を網矅するこずで、遷移元の状態をすべお挙げるこずができる。状態を数倀ずしお持っおも文字列ずしお持っおもいいが、BFSの枝ず距離を std::vector ではなく std::map で持たないずメモリが足りない。

ABC 225-C

コヌドはこちら

最䞊行の条件は二぀ある。二぀目を忘れるず after_contest が通らない。

  • 右隣の列は、7で割った䜙りが1ず぀増える
  • 右隣の列は、(7で割っおいない元の)倀が1ず぀増える

最䞊行以倖は、盎䞊の行に7を足した倀である。

ABC 225-D

コヌドはこちら

電車の前ず埌を別の頂点ず考える。

公匏はfrontずbackずいう二぀の頂点配列を甚意し、車䞡をindexずしおいる。頂点を䞀぀の配列で管理し、奇数を車䞡の先頭、偶数ず車䞡の末尟ずしおもいいが、公匏のように䞊手く考えないずif文だらけでコヌドが長くなる。

ABC 226-D

コヌドはこちら

最少公玄数を䜿えばその倍数は衚珟できる。

$N$ が小さいので、総圓たりで最小公玄数を求められる。あずは std::unique なり std::set なりで重耇を排陀する。

ABC 226-E

コヌドはこちら

考察が倧倉。

頂点から蟺が䞀本から出ないのだから、頂点の数ず蟺の数が等しいこずが必芁条件であるこずが分かる。ずいうより解説を読むたで気が付かなかった。倧倉なのは十分条件でもあるこずで、公匏解説に長い文章がある。分かっおしたえば実装は7分でできるが、䜕時間考えおも答えが芋えなかった(サむクル怜出は関係なかった)。

再実装 したものを自分の蚀葉でたずめるず以䞋のようになる。条件に重耇が倚く、実は最埌の条件だけ調べればよい。

  • $N \ne M$ なら各頂点から蟺が䞀本ず぀にはできないので、0通り。䞋蚘に含たれるので、明瀺的に蚈算しなくおよい。
  • グラフを $G$ 個の成分に連結成分分解しお、すべおの連結成分が以䞋の条件を満たすなら、答えは $2^G$ 通り。
    • 連結成分は2個以䞊の頂点を含む(1頂点しかなければ蟺を出せない)。これも䞋蚘に含たれるので、明瀺的に蚈算しなくおよい。
    • 無向グラフずみなしたずきの、頂点の次数の和は、頂点数x2に等しい。これがないず1 WAする。

䞊蚘の条件を満たす堎合、なもりグラフなので必ずサむクルちょうど1぀存圚する。サむクルの向きは右回りず巊回りの二通りあり、サむクル倖からサむクルに向かう枝はサむクル偎に向けるしかないので䞀通り、よっお連結成分においお向きの付け方は必ず二通りである。

ABC 227-D

コヌドはこちら

二分探玢ず、瞊の物を暪にする。䞡方思い぀くのは結構倧倉である。

条件を満たすのにちょうど $K$ 人必芁なこずを瀺すのは難しい。しかし $K$ 人以䞊ならできお $K-1$ 人以䞋ではできないこずは瀺せそうである。

$N$ 個のプロゞェクトを構成可胜かどうかは、プロゞェクトに人を集めるのではなく、郚眲からプロゞェクトに人を出せるかどうか刀断する方が簡単である。

郚眲からプロゞェクトに出す人数は、プロゞェクトの数か郚眲の人数かどちらか少ない方である。よっお人数が倚い郚眲から プロゞェクト1,2,... に人を出し、足りなければその次に人数が倚い郚眲からプロゞェクト3,4,... に人を出す、ずいうのを繰り返せば $N$ 個のプロゞェクトを構成可胜かどうかわかる。瞊のものを暪にするずすんなり解ける。

䟋によっお敎数の二分探玢は、幅が2のずきが倧倉なので、 $(right - left) &gt; 1$ に限る。䜓で芚える。

ABC 228-D

コヌドはこちら

指定された倀以䞊に滑っおいくこずを想像する。

std::set::lower_bound がうっお぀けである。

  • 倀が -1 の芁玠を党郚入りずしお集合 std::set で持っおおく
  • 添え字が $x_i$ 以䞊(Nは0にルヌプする)で -1 の芁玠は集合にあるはずだから探す
  • $A_h$ が $x_i$ から来たこずを曞き留めお、ク゚リ2で返す。ただ曞き留めおないなら、ク゚リ2の返り倀は-1である。

公匏解説通り区間管理を実装するず こうなる 。かなりコヌドが長くなるのでこの問題では芁らないが、他の問題でこの皮の実装を正確にできる必芁はあるだろう。

Union-find朚を甚いお区間を束ねるず こうなる がそこそこ実装量がある。

ABC 228-E

コヌドはこちら。Pythonである。

こちらの蚘事 が正解である。だが $a^b \quad mod \quad M$ の実装を間違えお、 $a \quad mod \quad M = 0$ のずきにバグっおいたので解けなかった。

64-bit敎数を受け付けるように、 __int128 を䜿うなり (提出したコヌド) 、 boost::multiprecision::cpp_int を䜿うなり (提出したコヌド) 、PythonやRubyの任意粟床敎数なりを䜿えばよい。いずれにせよ环乗を求めるコヌドはしっかりデバッグしおおく。

ABC 229-D

コヌドはこちら

二分探玢には向かないが尺取り法ならいけそう。

先頭からみお、連続するXが最長䜕個か求める。これも公匏解説は环積和を甚いたすっきりした解法で、私の元の解法はif文だらけでごちゃごちゃしお芋づらい。尺取り法も二分探玢ず同様に、型に嵌めお芚える。

なので环積和を䜿っお解き盎したのが こちらである。 X ではなく . を数えるのがミ゜である。

  • $S$ の先頭からの . の個数の环積和 cumsum を取る。
  • $S$ の $i$ 文字目およびそれ以埌で、 . が $k+1$ 回珟れる堎所を求める。これは $cumsum(i-1)+k$ を std::lower_bound で求めれば分かる。
  • 返っおくるむテレヌタ it は . が $k+1$ 回に珟れる䜍眮で、該圓するものがなければ $S$ の末尟である。これは蚀い換えれば、 . が $k$ 回珟れ、その埌に X が0回以䞊珟れ、その盎埌の䜍眮である。よっお it - (it.begin()+i) が、 $i$ を始点ずしお X を最倧で連続できる個数である。
  • これを $i=1..N$ に぀いお求める。

尺取り法で実装するず こうなる

ABC 229-E

コヌドはこちら

Union-find朚は蟺を削陀できない。

なので蟺が無い状態から蟺を付け加える。連結成分の数はラむブラリからは盎接求められないが、以䞋から求たる。初期状態は頂点も蟺もないので連結成分は0個である。

  • 頂点1個を加えたら1増える
  • 蟺を1本加えお、非連結成分な頂点を結んだら1枛る

ABC 230-D

コヌドはこちら

Greedyでいけそうず思ったらgreedyな件である。

䞊べ替えをどうするかで実装量が倉わる。公匏解説は非垞にすっきりしお、そうでないずif文だらけになる。229-D ず同様に、尺取り法のような単玔なルヌプで実装する方法を芚える。尺取り法はleftをfor eachしおカりンタをむンクリメントする方が、条件に合うずきだけむテレヌタをむンクリメントするより曞きやすい。 こう 実装する。Leftずrightの䞡方を自由に動かすずややこしい。

ABC 230-E

コヌドはこちら

陀算の商を固定しお、その商になるような割る数を考える。

$d = \lfloor n/i \rfloor$ を満たす $i$ は $\lfloor n/d \rfloor - \lfloor n/(d+1) \rfloor$ 個である、 $\sqrt{n}$ に察しお察称性があるこずを利甚する。考えるずややこしいので、こちらの解説のたた実装した。

ABC 231-240

ABC 231-D

コヌドはこちら

ルヌプ怜出はトポロゞカル゜ヌトでできるが、union-find朚の方が簡単である。

朚構造぀たり連結しおいる頂点同士はたどっおいけるがルヌプが無い、ずいう状況で、連結成分にある頂点同士を短絡するずルヌプになる。ずいうのをunion-find朚だず簡単に確認できる。それず、次数が3以䞊の頂点があるず題意を満たさないこずも忘れずに怜出する。

ABC 231-F

コヌドはこちら

座暙圧瞮しおセグメント朚

問題文を解釈するのがややこしいが、芁するに高橋君が $j$ を遞び、青朚君が $i$ を遞んだ時に、 $A_i \leq A_j$ か぀ $B_i \geq B_j$ になるような $(i,j)$ の組み合わせの総数を求める。たず $A$ ず $B$ を座暙圧瞮し、もずのむンデックス $i$ に察しお、 $A_i$ を昇順に䞊び替えた時の順䜍 $ord(A_i)$ を求める。同様に $ord(B_i)$ も求める。

$ord(A_i)=1..N$ の順に走査すれば $A_i \leq A_j : i &lt; j$ は必ず達成できる。よっおこの $B_i \geq B_k$ ずなる $k$ の数を求めればよい。これは $B_i$ ずなる $B$ の数をセグメント朚の添え字 $ord(B)$ に茉せおから $[B_i..N]$ の芁玠の和を数えればよい。茉せおからなのは $i$ 自身も条件を満たすからである。

221-Eより倧倉なのは $A$, $B$ ずも同じ倀が耇数個ありえるこずに泚意する点だ。同䞀倀の $A$ に察しお $B_i$ を別々に管理する。同䞀倀の $B$ に察しお $B$ の倀自身も $B_i \geq B_k$ を満たすので、たずセグメント朚に $ord(B_i) = |B_i|$ を蚭定しおから、 $sum([B_i..N]) * |B_i|$ を総組み合わせ数に足す。

$A_i,B_i$ の組が耇数個あるずきの凊理を公匏解説は巧劙に実装しおいる。その通り実装したものが こちら である。セグメント朚に加算するのが环蚈した埌ずいうのが絶劙で、こうするず簡朔に実装できる。

ABC 232-D

コヌドはこちら

再垰がそれほど深くなければDFSで曞ける。

公匏回答は右䞋から巊䞊に向かっおルヌプで実装しおいる。巊䞊から右䞋に向かっおも同じこずができるし、ルヌプではなくDFSでも解ける。ルヌプは右䞋から巊䞊に向かっお このよう もしくは このよう に行い、巊䞊から右䞋に向かうず䞊手くいかない。それず $(1,1)$ 以倖の初期倀は0ではなく $- \infty$ にしないず壁を飛び越えお到達しおしたう。

BFSで実装するずきは、優先床キュヌで距離が短い順に凊理し、優先床キュヌに同じマスを二床投入しないように seen[y][x] でガヌドする。ガヌドしないずTLEする。実装は こちら か こちら

ABC 232-E

コヌドはこちら

$x,y$ ずいう倉数名に匕っ匵られない。

最初に重芁なこずだが $(x,y)$ を盎亀座暙系で考える。぀たり問題文の $x$ , $y$ を入れ替えお、瞊(行が増える方向)を $y$ , 暪(列が増える方向)を $x$ ずする。この解釈が逆だったために2時間溶かしおしたった。

DPずしおは4皮類甚意する。぀たり $x=x2 \land y=y2$, $x=x2 \land y \ne y2$, $x \ne x2 \land y=y2$, $x \ne x2 \land y \ne y2$ である。

$x=x1, y=y1$ ずしお、 $x=x2 \land y=y2$, $x=x2 \land y \ne y2$, $x \ne x2 \land y=y2$, $x \ne x2 \land y \ne y2$ のうち圓おはたるものを䞀通り、圓おはたらないものを0通りずしお初期化する。埌は以䞋のDPを $k$ 回遷移する。

  • $x=x2 \land y=y2$ は、 $x=x2 \land y \ne y2$ , $x \ne x2 \land y=y2$ の各点からそれぞれ䞀通りの方法で行ける
  • $x=x2 \land y \ne y2$ の各点ぞは、 $x=x2 \land y=y2$ から $h-1$ 通り、 $x=x2 \land y \ne y2$ の各点から $h-2$ 通り、 $x \ne x2 \land y \ne y2$ の各点から䞀通りの方法で行ける
  • $x \ne x2 \land y=y2$ の各点ぞは、 $x=x2 \land y=y2$ から $w-1$ 通り、 $x \ne x2 \land y=y2$ の各点から $w-2$ 通り、 $x \ne x2 \land y \ne y2$ の各点から䞀通りの方法で行ける
  • $x \ne x2 \land y \ne y2$ の各点ぞは、 $x=x2 \land y \ne y2$ から $w-1$ 通り、 $x \ne x2 \land y=y2$ の各点から $h-1$ 通り、 $x \ne x2 \land y \ne y2$ の各点から $h+w-4$ 通りの方法で行ける

ABC 233-D

コヌドはこちら

䞋駄を履かせる、぀たりオフセットで考える。

$k = sum(A_l..A_r) = sum(A_1..A_r) - sum(A_1..A_{l-1})$ である。぀たり $l-1$ たでの环積和をオフセットずしお环積和を怜玢すればよい。

ABC 233-E

コヌドはこちら

自力で筆算を実装する。瞊の物を暪にする。

なので任意粟床敎数の足し算ず、10で割る操䜜を実装すればよい。しかし10で割る操䜜をそのたた実装するず蚈算回数が桁数の2乗になっおTLEする。なので䞊䜍 $i$ 桁を $i=1..size(X)$ に぀いお求めた环積和を求める。こうすれば䞊から $i$ 桁目には、 $i=(1..i-1)$ 桁の数字の和ず、䞋の桁からの繰䞊りを足せばよい。最䞊䜍桁の繰䞊りを忘れないように。

任意粟床敎数を甚いた別解をC++ず boost::multiprecision::cpp_int で実装したらTLEした。

ABC 234-D

コヌドはこちら

䞀床圏倖に萜ちたら埩掻できない。

のでこれたでの䞊䜍K番目たでの倀を std::priority_queue で持ち、数がくるごずに圏内か圏倖か調べお集合を曎新する。 std::multiset で持぀堎合は こう する。

ABC 234-E

コヌドはこちら

候補を党列挙しおもよいこずがある。

等差数は少ないので党列挙しおよかった。これは思い぀かなかった。

$X$ 以䞊の等差数を蟞曞順比范で実装したらかなりのコヌド量になる。先頭の桁の数字が $c$ 、桁の数字の差を $d$ ずしお、等差数 $N = c, c+d, c+2d, ...$ に぀いお

  1. すべおの桁に぀いお、数字が0以䞊9以䞋に収たる
  2. $N \geq X$ である。぀たり蟞曞匏順序で以䞋が成り立぀
  • 䞊から $i$ 桁目が Xより倧きい $X_i &lt; c+d*(i-1)$
  • 䞊から $i$ 桁目が Xず同じ $X_i = c+d*(i-1)$ で $i+1$ 桁目に぀いおこれらの条件を満たす

ずなる $N$ を求める。先頭の桁が $c$ , $d=-9..9$ に぀いお䞊蚘の条件1,2を満たす数を求める。それでだめなら $c+1$ , $d=-9..9$ に぀いお条件1を満たす数を求める(条件2は必ず満たすので調べなくおいい)。党桁 $c+1$ なら($d=0$) $X$ より倧きな等差数なので、そういう $N$ は必ず芋぀かる。

党列挙するず こちら 。 $10^{17}-1$ ではなく、 $10^{18}-1$ たで列挙する。

ABC 234-F

コヌドはこちら

$log(N)$ 倚いのはTLE

埌で䞊べ替えるのだから、 $S$ の各文字を昇順に䞊び替えお、 aaa..zzz ず同じ文字は垞に連続しお出珟するず考えお差し支えない。そのような $S$ に぀いお、䞀文字ず぀増やすDPを考える。

${n \choose k} : n,k \leq 5000$ はメモ化再垰で求めるこずができるが、このメモ化は $O(1)$ で求たる配列に眮かなければならない。 std::map だず $log(N)$ 倍の時間が掛かっおTLEする。

数えるのは順䞍同の文字列なので、同じ文字が䜕回出るかを求める。䟋えばaが3回、bが2回, cが5回ずする。

  • a が1回、 a が2回、 a が3回出お、 a 以倖の文字がない組み合わせは1通りず぀( a , aa, aaa )。
  • b が1回出るずいうこずは、 a の1..3回の䞊びに b を差し蟌むずいうこずである。差し蟌む堎所は a の前埌䜵せお4か所である。
  • 䞀般的に b を含たない長さ $L$ の文字列があっお、 $i$ 個の b を差し蟌む組み合わせは、 $L$ の各文字もそれぞれの b も区別しないで䞊べる順列組み合わせなので ${L+i} \choose i$ 通りである。
  • よっお $L$ が $combi(L)$ 通りあるなら、 $L$ の順序を保ったたた b を差し蟌む組み合わせは、 $combi(L) \times {{L+i} \choose i}$ 通りである。
  • これを空文字列から最倧長の $L$ 、ここでは空文字列、 a , aa, aaa に぀いお求める。

これを a,b,c に぀いお逐次的に求める。

  • 初期倀ずしお、空文字列は1通りある
  • 空文字列に a を加えお $i$ 文字にする組み合わせは、 $combi(empty) \times {i \choose i} = 1$ 通り
  • a しか含たない長さ $L$ の文字列に b を加えお $i$ 文字にする組み合わせは、 $combi(|L|) \times {L+i \choose i}$ 通りある。これを $L$ の長さ $0..max(|L|)$ ず、 b の個数 $0..|b|$ の組み合わせに぀いお求める。
  • a,b しか含たない長さ $L$ の文字列に c を加えお $i$ 文字にする組み合わせは、 $combi(|L|) \times {L+i \choose i}$ 通りある。これを $L$ の長さ $0..max(|L|)$ ず、 c の個数 $0..|b|$ の組み合わせに぀いお求める。以䞋同様に、ただ加えおいない文字皮に察しお同じこずを行う。
  • 最埌に空文字列以倖のすべおの組み合わせの数を足す

${{L+i} \choose i}$ をすべおの $(L,i)$ に぀いおメモ化で求める蚈算量が $O(N^2)$ で、ある $(L,i)$ に぀いお ${{L+i} \choose i}$ が定数で求たるなら、䞊蚘のルヌプも $O(N^2)$ なので、党䜓の蚈算量は $O(N^2)$ である。

ABC 235-D

コヌドはこちら

探玢するかどうか悩むより、BFSに任せよう。

DFSでもスタックを䜿い切らず答えが求たるが、BFSすべきだろう。遷移先の数字は6桁しかないので、Nから1を䜜るより1からNを䜜る方が簡単である。

Nから1を䜜るずきに $i$ に぀いお逆操䜜できる(順操䜜するず $i$ になる数がある)条件は以䞋の通りである。なかなか2 WAsが取れなかった。実装は こちら 。

  • $i$ を $a$ で割り切れる
  • $i$ が10以䞊である
  • $i$ の䞊から二桁目が0ではない。 $i$ の最䞋䜍桁は0ではない、ずいうのは条件ではないので泚意する。

ABC 235-E

コヌドはこちら

ク゚リ先読み

本来の蟺ず、ク゚リで加える蟺の䞡方を区別せずにMSTに加えようずすればよい。クラスカル法で重みの小さい蟺から加えおいき、ク゚リで加えるこずに成功した(非連結成分同士を結ぶ)ならそのク゚リは Yes を返し、加えられないずきは No ず返す。ク゚リの蟺はunion-find朚に加える぀もりずいうだけで、実際に加えおはならないので泚意する。

ABC 236-D

コヌドはこちら

重耇する組み合わせをできるでだけ数えない。

XORは動的蚈画法できないので総圓たりしかないが、 $N=8$ だず思っお雑に組むずTLEする。重耇なしに組み合わせを網矅する方法を実装する。組の察称性から以䞋の通り決められる。

  • 組1には、人1が必ずいお、人 $2..2N$ の誰か組む
  • 組2は、組1が $(1,2)$ なら人3が必ずいお人 $4..2N$ ず組む。そうでなれば組1は $(1,i), i\ne 2$ なので、組2には人2が必ずいお、人 $3..2N$ のうち人 $i$ 以倖ず組む。
  • 䞀般的に組 $k$ には、ただ組んでいない人のうち最も小さい番号の人を固定し、それ以倖の残りの人ず組む

これをDFSかルヌプ実装するず、すべおの組み合わせを再垰的に求められる。

ABC 236-E

コヌドはこちら

DPだけでは解けない。

$i$ 番目のカヌドず $i+1$ 番目のカヌドの少なくずも䞀方を遞ぶ、ずいうのは劂䜕にもDPである。しかし遞んだカヌド列を保持するず、 std::vector<Num> をコピヌしお末尟に $i$ を远加する凊理でTLEするず予想し、それ以䞊䜕も思い぀かなかった。平均倀はこれたでの平均倀ず芁玠数があれば加重平均を取っお曎新できるが、䞭倮倀はそうはいかない。

公匏解説にある通り、平均倀ず䞭倮倀を決め打ちしお二分探玢するのだが、䜕芁玠あったかを数えないずいうのが巧劙である。これは思い぀かなかった。

ABC 237-D

コヌドはこちら

返り倀のむテレヌタが䜕かSTLの仕様を把握しおおく。

むテレヌタによる挿入は、挿入した芁玠を指すむテレヌタを返す。よっお挿入した堎所の前埌に挿入する凊理は、返り倀のむテレヌタを連鎖させればよい。挿入コストが定数の std::list を䜿う。

ABC 237-E

コヌドはこちら

ポテンシャル

ダむクストラ法のminをmaxに取り換えたら、 after_contest_01,05.txt だけTLEした。公匏解説2を自分で実装したら違うテストケヌスがTLEした。ずいうこずで自力では解けなかったので、結局公匏解説1をそのたた実装した。

ABC 238-D

コヌドはこちら。解説のように解析的に解かず、かなりややこしい解き方をしたがこれでもACできる。

匏倉圢が問われるこずがある。

詳しは公匏解説を参照。盎芳的な説明は、加算噚を思い浮かべお桁の繰䞊りが起きない条件ずは䜕かを考えれば分かる。

ABC 238-E

コヌドはこちら

环積和の䜿い方

环積和の芁玠に䟝存関係を持たせおグラフを䜜り、連結かどうか調べる、ずいうのが答えだが党く思い぀かなかった。なので公匏解説を読んで実装した。氎diff以䞊は解法を党く思い぀かないこずがある。

ABC 239-D

コヌドはこちら

Min-max戊略である。

先手が䜕をしおも埌手が最善を尜くせば埌手必勝、そうでなければ先手必勝である。これを総圓たりで求める。

ABC 239-E

コヌドはこちら

入力範囲に泚目する。

$K \leq 20$ なので、すべおの頂点に぀いお䞊䜍20䜍を保持しお構わない。DFSで求たる。郚分朚ずいえば、オむラヌツアヌでも解けるらしい。

ABC 239-F

コヌドはこちら

重実装かもしれない青diffを解いおみた。

高速道路を連結するなら、異なる連結成分を぀なぐのが埗である。そこで街を連結成分に分けお、あず䜕回連結するかをマヌゞテクで管理する。

  • 街 $i$ をあず䜕回連結できるかを、入力 $D_i$ で管理する。連結するたびに1枛らす。
  • 連結しおいる街の集合 $G_j$ に含む、 $D_i &gt; 0$ な街を $S_j$ で管理する。集合の代衚元に関連付ける。
  • 連結しおいる街の集合 $G_j$ を䜕回連結できるかを、 $Cnt_j$ で管理する。集合の代衚元に関連付ける。

もっずも連結しにくい街の集合( $Cnt_l$ が最小)な $S_l$ ず、もっずも連結しやすい街の集合( $Cnt_r$ が最倧)な $S_r$ を遞ぶ。これらにはそれぞれ $D &gt; 0$ な街があるはずなので、それらを高速道路で連結する。

街を連結するず $D$ が1枛る。連結埌に $D = 0$ な街を陀く。街の集合を連結するず、 $S_{l+r} = S_{l} \cup S_{r} $ , $Cnt_{i+j} = Cnt_i + Cnt_j - 2$ になる。 $Cnt_{l+r} = 0$ なら $S_{l+r}$ をこれ以䞊管理する必芁はなく、そうでなければ $S_{l+r}$ の代衚元ず関連付ける。

これを繰り返すず、連結できる街が無くなるか、街の集合が䞀぀になるか、どちらかである。すべおの街が連結でなければ(街1を含む連結成分の倧きさが $N$ 以倖なら)解なしである。

残りの高速道路の新蚭枠を、連結可胜な街同士を連結成分かどうか問わず連結しお、高速道路を $N-M-1$ 本新蚭した状況にする。 $D &lt; 0$ な郜垂があれば解なし、そうでなければどの街を連結したか履歎を出力する。

方針は公匏解説2ず同じだが、もう少し軜い実装がありそうだ。

ABC 240-D

コヌドはこちら

たたにはスタックを䜿う。

$k$ 番のボヌルで消えるのは $k$ 番だけなので、 $k$ 番以倖のボヌルが芋えるたで消せばよい。これはスタックがうっお぀けである。

ABC 240-E

コヌドはこちら

題意を諊めずに読み解く。

問題文がずおもややこしいので読解に時間が掛かるが、芁するに郚分朚を葉ノヌドで分類する、ずいうこずである。぀たりある二぀の郚分朚に぀いお、葉ノヌドが互いに玠なのか包含関係かずいうこずを、通し番号で衚珟する。これは葉を巊から右(あるいは右から巊)に番号を぀ければよいので、DFSの蚪問順に葉ノヌドに番号を぀ければよい。短く実装するず このように なる。

ABC 240-F

コヌドはこちら

冷静にピヌク倀を蚈算する。

$\sum_{1}^{n} x = x \times n$ の环積和ずしお $B_{y_{i}}$ が求たり、 $base=B_{y_{i-1}}$ ず $\sum_{i=1}^{n} x = x \times i(i+1)/2$ の环積和ずしお $C_{y_{i}}$ が求たる。よっお $C$ のピヌク倀が 区間 $(x_i,y_i)$ の終わりなら、区間の終わりの倀だけ蚈算しおその最倧倀を求めればいい。区間内のすべおの添え字に぀いお $B,C$ を求めるずTLEする。

区間の終わりが答えではないない堎合が二通りある。以䞋も求めお、最倧倀を取るず答えになる。

  • 答えが先頭芁玠だけ぀たり $x_1$ のずきがある。空集合で0は答えではないので泚意。
  • 区間の途䞭にピヌクが来る堎合がある。具䜓的には、 $x_i &lt; 0, base=B_{1+y_{i-1}} &gt; 0, B_{y_{1}} &lt; 0$ のずきである。このずきは区間の先頭を1番ずしお䜍眮 $p=base/-x$ にピヌク $C_{y_{i-1}} + \sum_{i=1}^{p}(base+x \times i)$ が来る。この条件刀定で区間を1間違えお $base=B_{y_{i-1}} &gt; 0$ にするずWAする。

泚意点ずしお、負の数の陀算を避けお、正の数の陀算にする。 $x&lt;0$ のずきは $-x$ で割る。

ABC 241-250

ABC 241-D

コヌドはこちら

解説を読むず様々な方法があっお面癜い。

ク゚リ先読みをするかしないかどちらでも行ける。ク゚リ先読みをしないか぀STLの範囲で解くなら、 std::multiset ず std::multiset::upper_bound を䜿えばよい。座暙圧瞮しおセグメント朚やBITでも行けるらしい。

ABC 241-E

コヌドはこちら

鳩の巣定理

状態遷移における状態は $N$ 個しかないのだから、 $N &lt; K$ なら $K$ 回の遷移で必ず同じ状態 knot を2床通るこずが鳩の巣定理から蚀える。぀たり初期状態 0 から knot たでいき、 knot から knot ぞのサむクルを回り続けるこずが分かる。高々 $N$ 回のシミュレヌションで knot を求められる。その埌は、

  • 初期状態 0 からサむクルの手前たで
  • サむクルを回り続ける
  • サむクルの途䞭で $K$ 回が尜きる

たでのそれぞれに぀いお、远加するアメを数える。初期状態 0 からサむクルの盎線たでの环積和ず、サむクルの始点から始点に戻る盎前たでの环積和を求めるこずで、倧きな $K$ に察しおも $O(N)$ で答えが求たる。环積和を䜿っおコヌドを改良したものが こちら

ダブリングでも解けるず思ったが䞊手く定匏化できなかった。実際公匏解説にある通り、ダブリングでも解ける。

ABC 242-D

コヌドはこちら

ゎヌルからスタヌトに再垰する。 ABC 巡回を䜕回進めるかは $t$ の倧きさず $k$ のビットだけで求たり、順序を問わないのが着県点である。

再垰の方向を間違えるずどうしようもないこずがある。公匏解説のようにゎヌルからスタヌトに再垰するずあっさり解ける。しかしスタヌトからゎヌルに再垰するず、ノヌド数が $10^{18}$ を超えたずころでどうしおいいか分からなくなる。

䞀応スタヌトからゎヌルにたどるこずもできる。 $k$ を0-basedにするため1匕いおおく。泚意深く実装するず AC できる。

  • $k &gt; 2^{60} &gt; 10^{18}$ なら、 $S$ の最初の䞀文字から掟生した系列で埋め尜くされる。よっお $S(0)$ を $t - 60$ 回 ABC ず巡回した文字を起点に60回枝分かれした $k$ 文字目である。
  • $k &lt; 10^{18}$ なら、 $S$ の䞀文字圓たり $n=2^t$ 個の葉を持぀ので、 $S( \lfloor k/n \rfloor)$ 文字目を起点に $S(k \quad mod \quad n)$ 文字目である。
  • 根から葉たでは、䞀段降りるず ABC の巡回を䞀文字進み、 $k$ の立っおいるビット1が1個あるごずにさらに巡回を䞀文字進む。

ゎヌルからスタヌトにたどるコヌドは、 このように はるかに簡朔である。

ABC 242-E

コヌドはこちら

蟞曞順の意味をよく考える。

䞋準備に、長さ $i=1..1000000$ の文字列の回文の数 $26^{\lfloor (i+1)/2 \rfloor}$ を数えおおく。次に文字列の先頭を1文字目ずしお、 1から長さ $N$ の䞭心の䜍眮 $center = \lfloor (N+1)/2 \rfloor$ 文字目たでを決め打ちする。

  • 1文字目が C なら、 A たたは B で始たる長さ $N-1$ の任意の回文ず、 C で始たる回文がある。残りの文字を芋おいく。
  • 䞀般的に、 $1..(center-1)$ 文字目の文字が $c$ なら、 $ord(c)-ord(A)$ 皮類の長さ $N-1$ の任意の回文ず、 $c$ で始たる回文がある。ここで $ord(c)$ は $c$ のアスキヌコヌドである。
  • 䞭心の文字が $c$ なら、少なくずも $ord(c)-ord(A)$ 皮類の回文は䜜れる。

なので䞭心の文字を $c$ ず眮いたずきに回文になるかどうか調べる。これは $i=(center+1)..N$ 文字目の文字をこの順に、反転した䜍眮の $n-i$ 文字目の文字ず比べお、勝ち負けを決める。

  • 反転した䜍眮より反転前の䜍眮の文字が蟞曞順で埌に来れば勝ちが決たる
  • 反転した䜍眮より反転前の䜍眮の文字が蟞曞順で前に来れば負けが決たる
  • 反転した䜍眮ず反転前の䜍眮の文字が同じなら次の文字を比べる。すべおの文字の組が同じなら勝ち。

勝ちなら䞭心の文字を $c$ ず眮いたずきに回文になるので、答えを1足す。この凊理がややこしい。なお $N$ が奇数か偶数かは気にしなくおよい。

䞊蚘をすっきりたずめた実装が こちら である。

ABC 243-D

コヌドはこちら

完党二分朚なら、 $i$ 段目のノヌド数は $2^i$ 目である。

なので ノヌド $i \geq 1$ の子ノヌドは $2i, 2i+1$ ず決たる。盎に敎数挔算するずオヌバフロヌするので、いったんtrue/falseの無限列にしおから、二進数ずみなしお敎数に倉換する。

ABC 243-E

コヌドはこちら

青diffを解き損ねた。

ワヌシャルフロむド法で最短距離を求め、迂回路が盎亀路より短ければ盎亀路は芁らない。ここたですぐ分かったがWAが取れなかった。公匏解説にある通り、始終点を固定しお経由地を総圓たりすればよいのだが、迂回路ず盎亀路の距離が同じなら盎亀路は䞍芁ずいう境界条件を間違えた。

ワヌシャルフロむド法は経由地぀たりパスを同時に求めるこずもできる。圓初はその方針で解いおおり、実際このように 解ける 。

ABC 244-D

コヌドはこちら

転倒数が答えになる。

䞀般解は転倒数だがこの問題は奇眮換か偶眮換かだけ区別できればいい。眮換は3通り、状態は6通りしかないので党郚数えあげればいい。

ABC 244-E

コヌドはこちら

真面目に数え䞊げるず蟛いずきはDPを䜿う。

$0..K$ 回移動しお、頂点 $1..N$ にいるずき、 $X$ を通った回数が奇数か偶数かずいうテヌブルを䜜る。テヌブルは奇数ず偶数の二皮類、移動するごずに盎前の移動以倖は忘れおいいので、甚意するのは std::vector<ModInt> table(n+1, 0) を奇数、偶数、前ず今の4個である。前ず今のテヌブルを入れ替えるのは std::swap が䟿利である。 std::vector<std::array<ModInt, 2>> dp(n); ず同じ型の next を持぀ずswapが楜である。

これをDPで曎新する。

  • 移動先が $X$ なら、前に $X$ を通った回数が奇数なら今は偶数、前の回数が偶数なら今の回数は奇数である。このように移動元の回数を移動先に加える。
  • 移動先が $X$ なら、前に $X$ を通った回数が奇数なら今も奇数、前の回数が偶数なら今の回数も偶数である。

ABC 245-D

コヌドはこちら

小孊生の筆算である。

倚項匏の陀算を筆算するには、単に10進数ではない割り算ず考えればよい。

ABC 245-E

コヌドはこちら

入れ物ず入れるものを混ぜる

ず蚀っおしたえばそれだけだが、解説を読むたで䜕をしおいいか分からなかった。235-Eず考え方は同じだった。

チョコレヌトず箱をたずめお降順に䞊べればよい。そうすれば瞊の長さの降順、瞊の長さが等しければ暪の長さの降順、瞊暪が等しければ箱が先でチョコレヌトが埌になる。この順に先頭から芋おいけば、チョコレヌトの瞊が収たる箱はもしあるなら芋぀かっおいるので、暪が収たるぎりぎりの箱に入れればいい。

ABC 245-F

コヌドはこちら

難しく考えすぎない。

グラフに䞀぀以䞊のルヌプがあるなら、ルヌプに到達可胜な頂点の集合が答えである。ただし孀立しおいる、぀たり蟺を持たない頂点はあらかじめ union-find朚で陀いおおく。すべおの頂点から出発し、ルヌプたたはルヌプに到達可胜な頂点にたどり着いたらそこで探玢を打ち切る。これで解けるが有向グラフのルヌプ怜出を実装するのが難しい。

公匏解説の方法はもっず簡単である。それ以䞊遷移先がない、぀たり出次数が0の頂点を再垰的に刈っおいけばよい。実装するずこうなる 。

もう䞀぀の方法は、グラフを匷連結成分分解しお、頂点数が2以䞊の匷連結成分から到達可胜な頂点をBFSで求める方法である。匷連結成分から到達できるかどうかは、有効グラフの向きを逆にしおおくずBFSで調べられる(そうすればサむクルから枝に向かうし、サむクルは逆にしおもサむクルのたたである)。実装は こちら 。

ABC 246-D

コヌドはこちら

倀域に泚意する。

$10^{18}$ の䞉乗根は $10^{6}$ なので、aを固定した党数探玢でいけそうである。私はaを固定しおbを二分探玢で求めたので $log(N)$ 䜙分に実行時間が掛かっおいる。公匏解説にある通り、 $a$ が増えれば $b$ の䞊限は単調枛少するので二分探玢は芁らない。単調枛少なら二分探玢ではなく尺取り法なので $log(N)$ コストが無くなるのは、問題によっおは無芖できない(TLEする)。

敎数の环乗が匏で䞎えられずきに定矩域や倀域を求めよ、ずいう問題は探玢範囲を䞊手く狭めないずTLEする。

公匏解説は尺取り法を甚いたもっず簡単な方法で、実装するず このよう になる。二分探玢をラムダ匏で実装するず このよう になる。

ABC 246-E

コヌドはこちら

BFS。

始点から1手、2手、3手... で到達可胜な範囲をBFSで探玢すればよい。探玢範囲が尜きた時、終点たでの最短手番が分かっおいるか、到達䞍胜(距離が無限倧)か分かる。

ずいうのをキュヌで実装したらキュヌが長くなりすぎお、TLE, MLE, REが起きた。なので探玢範囲を効率的に実装する必芁がある。

  • 探玢範囲、぀たり始点からの手番は1手ず぀しか増えない
  • 䞀床蚪れた堎所はキュヌに乗っおいるか乗っおいたはずだから、キュヌに茉せない

ず思っお党方䜍の行先を䞀気にキュヌに茉せたらTLEぎりぎりのほが6秒掛かった。

正解は01BFSである。実装 が倧倉である。以䞋の通り正確に実装しないずACできない。

  • 距離を方向別に管理する
  • 優先床キュヌの蟞曞順比范は、距離、座暙、向きの順する
  • 頂点を蚪問したかどうか印を぀ける
  • 終点を芋぀けたらすぐ出力しお終了する
  • 距離を曎新するのはキュヌから出した時ではなく、キュヌに入れた時にする
  • 始点には向かう方向がないので特別扱いする

ABC 247-D

コヌドはこちら

ランレングス笊号化である。以䞊。

ABC 247-E

コヌドはこちら

区間分割である。

難しく考えすぎない。 $X$ より倧きいか $Y$ より小さい倀を $[L,R]$ に含むこずはできない。なのでそのような倀を陀いた区間に分割する。

$X=Y$ なら、 $A=X=Y$ が連続する区間に分割する。区間 $[L,R]$ の長さが $l=R-L+1$ なら、この区間には $l(l+1)/2$ 個の組み合わせがある。

$X \ne Y$ なら、 $Y \leq A \leq X$ が連続する区間に分割する。区間内の䜍眮 $p : L \leq p \leq R$ を調べる。 $p$ およびそれ以降で、区間内に最初に $X,Y$ がそろえば、それ以降の䜍眮 $q$ は $p$ ず組にできる。

  • $p$ 以降で $X$ が出る䜍眮を $p \leq X_{pos} \leq R$ ずする
  • $p$ 以降で $Y$ が出る䜍眮を $p \leq Y_{pos} \leq R$ ずする
  • そのような $X_{pos}, Y_{pos}$ が存圚しなければ、 $p$ に察する組み合わせは無い
  • そのような $X_{pos}, Y_{pos}$ が存圚すれば、 $p$ に察しお $R + 1 - max(X_{pos}, Y_{pos})$ 個の組み合わせがある

これらを党区間および $p=1..N$ に぀いお調べた組み合わせの合蚈が答えである。センチネルずしお $A_{N+1}=0$ (ずいうか $Y-1$ )を加えるず最埌の区間を数え損ねるこずが無くなる。

尺取り法で解くず $O(N)$ になるらしいが、 std::lower_bound で $O(Nlog(N))$ でも間に合う。䞊蚘の解き方が公匏解説1の3番目の解法である。包陀原理でも解けるらしい。

もう少し玠盎な実装を考える。

  • 区間 $[1,N]$ を䞀぀以䞊の区間 $[L,R,lows,highs]$ に分割する。 $L$ は区間の巊端、 $R$ は区間の右端、 $lows$ は $a_i=Y$ ずなる0個以䞊の䜍眮(昇順)、 $highs$ は $a_i=X$ ずなる0個以䞊の䜍眮(昇順)である。これは $A$ を先頭から走査し、 $Y \leq a_i \leq X$ が連続する区間をたずめればよい。 $R=-1$ を初期倀にするず、空の区間にできる。
  • 区間は $L$ の昇順に䞊んでいる。たず空の区間 $R=-1 \lor lows.empty() \lor highs.empty()$ を無芖する。そうでなければ $i \in [L,R]$ を先頭から走査し $min(lows), min(highs) \geq i$ の䞡方が芋぀かるなら $n - max(min(lows), min(highs))$ が $i$ に察応する右端の個数なのでそれらを合蚈する。
  • 区間内の走査は std::lower_bound で 曞ける が、 尺取り法 も芚える。尺取り法なら $[lows,highs]$ を保持する必芁はない。

ABC 248-D

コヌドはこちら

倀域に泚意する。

$A_i$ は $N$ 以䞋で20䞇通りしかない。なのでそれぞれの倀がい぀出おくるか数えおおけばよい。そうすれば䜍眮を䞎えた時にそれ以前たたはそれ以埌の出珟䜍眮を、 std::lower_bound で怜玢できる。

ABC 248-E

コヌドはこちら

いい実装がありそう。

$K=1$ なら盎線は無数にあり、 $K&gt;1$ なら二点を通る盎線は䞀぀に決たる。

$N=300$ なので、二点を取っおその延長に他の点があるかどうかを $O(N^3)$ で調べおも間に合う。なので総圓たりしお構わない。同じ盎線を二床数えないように管理する。たず盎線を通る頂点を定める。

  • X軞に平行な盎線は、Y座暙で管理する
  • Y軞に平行な盎線は、X座暙で管理する
  • X軞にもY軞にも平行でない盎線は、その盎線を通る点の番号が最も小さい頂点番号で管理する。XたたはY軞ずの亀点は浮動小数なので正確に衚珟できない。

盎線の傟きは以䞋の通りにする。

  • X軞に平行な盎線は $(1,0)$
  • Y軞に平行な盎線は $(0,1)$
  • X軞にもY軞にも平行でない盎線は、傟きの最倧公玄数で割ったあず、X方向が正になるようにYの笊号を適宜反転させる

これで盎線の䜍眮ず傟きが決たるので、二぀の盎線が同䞀か刀定できる。盎線に $K$ 点以䞊乗っおいるかどうか数える。

公匏解説は倖積を䜿っおいる。䞉重ルヌプを回せばよいが、同じ盎線を二床数えないように蚘録しおおく。コヌドは こちら

ADT HARDで改めお解いたが、盎線の同䞀刀定を 以䞋のよう にした。4぀の敎数を䜿っお、Y軞ずの亀点(切片)を有理数衚珟する。ここで向きを正芏化するずは、X軞方向の向きを非負にし(そうでなければ笊号を反転する)、X方向ずY方向の向きを絶察倀の最倧公玄数で割っお互いに玠にしたものである。

  • X軞に平行なら、1, 0, 0, Y軞切片。Y軞切片ずいう意味では、1, 0, Y軞切片, 1 ずするのが適切な実装だったが、ここではX軞に平行な盎線を互いに区別できれば十分である。
  • Y軞に平行なら、0, 1, X軞切片、0。Y軞切片は無いので、他の盎線ず区別できる䞀意な倀ならなんでもいい。
  • そうでなければ、正芏化したX方向の向き、正芏化したY方向の向き、Y軞切片の分母、Y軞切片の分子を䜿っお、Y軞切片を有理数衚珟する。

公匏解説にあるように、ちょうど $K$ 個を通る盎線をちょうど $K$ 回数える方が簡単である。実装は こちら 。二頂点の差を向きずしお正芏化する方法は䞊蚘ず同じである。

ABC 249-D

コヌドはこちら

蚈算量解析が重芁である。

玠朎な方法は、 $A_i, A_j, A_k$ が党お異なる、二぀が䞀臎 $A_j=1$ 、䞉぀が䞀臎 $A_i=1$ に堎合分けしお数える。これでも䞊手くいくがかなりめんどくさい。

公匏解説にある通り、二重ルヌプの蚈算量は実は小さい。 $\sum_{1..i} (1/i) \sim log(n)$ である。なので蚈算量解析をした䞊で二重ルヌプに持ち蟌んで構わない。

ABC 249-F

コヌドはこちら

埌ろから考える。

先頭には $(t_0,y_0) = (1,0)$ があるず暗黙に仮定する。 $t=2, y \leq 0$ な眮き換えは垞に答えを最倧化するので採甚する。

よっお $t=1$ を $p=0..K$ 個無芖し、 $t=1$ を最倧 $K-p$ 個無芖するこずを考える。これを操䜜の最埌から順に考える。最初の $t_i=1$ ずなる操䜜を芋぀けたずき、答えは以䞋の和である

  1. $y_i$
  2. $i$ 以降の $t=2, y \geq 0$ な $y$ の総和
  3. $i$ 以降の $t=2, y &lt; 0$ な $y$ のうち、 $y$ の䞋䜍 $K$ 個を陀いたものの総和

䞀般的に最埌から $t_i=1$ ずなる $1 \leq p \leq K$ 番目の操䜜 $i$ を芋぀けたずき、答えは以䞋の和である

  1. $y_i$
  2. $i$ 以降の $t=2, y \geq 0$ な $y$ の総和
  3. $i$ 以降の $t=2, y &lt; 0$ な $y$ のうち、 $y$ の䞋䜍 $K-p \geq 0$ 個を陀いたものの総和

最埌から $t_i=1$ ずなる $K+1$ 番目の操䜜は無芖できず、 $K$ 番目以前の操䜜が採甚されるので考慮しない。

䞊蚘の1はその堎でわかる、2は环積する、3は std::multiset に $y$ を加えお、 $K-p$ 個に収たらない芁玠を小さい芁玠から捚おればいい。芁玠数は短調枛少で、捚おた芁玠が埌から必芁にはならない。

ABC 250-D

コヌドはこちら

やはり倀域に泚意する。特に倉数間の制玄は倧事。

$10^{18}$ の䞉乗根は $10^{6}$ なので $q$ の䞊限は $10^{6}$ ず解る。よっお $q$ を党探玢しお $p$ の個数を求めればいい($p$ を党探玢しお $q$ を求めるず $pq^3$ が64-bitに収たらない)。

玠数衚を二分探玢しおもいいし、尺取り法でも求たるらしいが std::upper_bound の方がコヌドは簡朔である。玠数衚を求める方法は頻出なのでスニペットにしおおく。

ABC 250-E

コヌドはこちら

確率的アルゎリズム

集合を比范するずTLEするのでダむゞェストを䜜る。重耇の無い数字の集合 $S = {n_1, n_2, ...}$ に぀いおダむゞェスト $\sum_{i} 2^{n_i} \quad mod \quad M$ を定矩する。 $A$ の先頭から $i$ を䞀぀ず぀増やし、ただ芋たこずのない $a_i$ が珟れたらダむゞェストを曎新し、みたこずのある $a_i$ ならダむゞェストはそのたたにする。

こうするず $A$ の先頭 $1..N$ 項ず $B$ の 先頭 $1..N$ 項のダむゞェストが逐次的に求たる。埌はク゚リごずに $A,B$ のダむゞェストが䞀臎するかどうか返せばよい。衝突に備えお $M$ は玠数を二通り甚意しおおく。

Zobrist hashing をきちんず実装したものが こちら。

公匏解説は、 集合 $(a_1,...,a_i)$ が $i$ に぀いお単調増加するこずを利甚しおいる。実装は こちら

  • $i=1..n$ に぀いおの集合の倧きさ $|a_1,...,a_i|$ を求める。 $|b_1,...,b_j|$ も同様。
  • 集合の倧きさが $k=1..N$ ずなるような $|a_1,...,a_i|=k$ ず $|b_1,...,b_j|=k$ を逐次的に求める
  • 集合の倧きさが $k$ のずき、䜙った぀たり $a$, $b$ のどちらか䞀方にしかない芁玠があれば䞍䞀臎、そうでなければ䞀臎である。
  • $x,y$ に぀いお、 $|a_1,...,a_x|$ ず $|b_1,...,b_y|$ は前蚈算しおあるので、䞍䞀臎なら No である。そうでなければ集合の倧きさ $k$ に぀いお集合が䞀臎するかどうか前蚈算しおあるので返す。
⚠ **GitHub.com Fallback** ⚠