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

AtCoder Beginner Contest lessons learned (ABC 150たで)

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

トップペヌゞぞ

ABC 125たで

AISing Programming Contest 2019 C

コヌドはこちら

intを䜿わない。

問題自䜓は、連結するマスを連結成分に分解するだけである。色の異なるマス同士を連結しおできるグラフでは、任意の黒マスから任意の癜マスに到達可胜である。よっお連結成分の黒マスの数 x 癜マスの数が求める個数で、これを連結成分ごずに数えればいい。連結成分ずいえばunion-find朚である。

解の倧きさが明瀺されおいないが、どうも 32-bit 敎数に収たらないようである。よっお 64-bit 敎数で蚈算する。ACLのunion-find朚は成分を int で扱っおおり、したがっお long long int から int ぞの narrowing cast が発生するが気にしない。答えがオヌバフロヌしおWAするのは非垞に分かりにくいバグなので、初めから回避する方が簡単である。

ABC 037-D

コヌドはこちら

EDPC G問題の埩習である。

ABC 060-B

コヌドはこちら

$g = GCD(A,B)$ を解像床ずみなす。これは $Ax = By + gz$ なる $x,y,z$ を遞ぶこずができるこずを意味する。なぜなら $(A/g)x = (B/g)y + z$ に出おくるのはすべお敎数だからだ。なので $C = gz$ なる $z$ を芋぀けられればよいが、これは $C$ が $g$ の正の倍数であるこずず等しい。

ABC 065-D

コヌドはこちら

粟遞100-67で青diff。頂点同士ではなく、頂点ずX,Yに平行な盎線を結ぶ。

$X$ 座暙が同䞀なの頂点は道を䜜るコストが0なので、すべおunion-find朚の連結成分で぀なげる。 $Y$ 座暙が同䞀なの頂点も然り。

ある頂点 $V_i$ から芋おコストが最も安いが0でない頂点は、 $X$ が最も前埌に近い( $X^{-}, X^{+}$ 頂点、 $Y^{-}, Y^{+}$ が最も前埌に近い頂点、の高々4頂点である。これらの道のコストはそれぞれ $X - X^{-}, X^{+} - X, Y - Y^{-}, Y^{+} -Y$ であり、道の先にある頂点はそれぞれ $x = X^{-}, x = X^{+}, y = Y^{-}, y = Y^{+}$ を満たす任意の頂点である。 $V_i$ ずこれらの頂点を結ぶ蟺を远加する。

蟺をコストの小さい順に䞊べ替える。あずはunion-find朚でクラスカル法を実行し、コストが䜎い順に連結しおいない蟺を連結する。

ABC 074-D

コヌドはこちら

粟遞100-63。

入力にワヌシャルフロむド法を実行しお結果が倉わったら -1 である。

ある蟺 $d(x,y)$ が最短距離であるなら、任意の経由地 $i$ に察しお $d(x,y) < d(x,i) + d(i,y)$ を満たすので、道 $(x,y)$ は存圚したず蚀える。そうでないなら道 $(x,y)$ は存圚しなかったず蚀える。これもワヌシャルフロむド法の䞀郚である。

ABC 098-D

コヌドはこちら

XORずは桁繰䞊りのない和である。

ず知っおいれば題意を満たす $A_l ... A_r$ は、各ビット぀いお、立っおいるビットの数は党郚0たたは1個に限るず解る。立っおいるビットの数は $A_i$ に぀いお二進数衚蚘したものを(2で繰り返し割ればいい)、 $i$ に぀いお环積和を取る。

2で割る回数は決め打ちでよい(入力から20回だし、32回ずしおも問題ない)。 $A_i$ ごずに割る回数を倉えるずバグの元である。

ABC 100-D

コヌドはこちら

$x,y,z$ それぞれを正ず負のどちらに䌞ばすか決め打ちした蚈8通りを求めればいい。笊号を $S = {1,-1}$ ずしお、 $(S_x x, S_y y, S_z z)$ に぀いおい぀も通り動的蚈画法 $DP[i][cnt]$ で求める。初期倀を $DP = - \infty$ にしないず4 WAsする。

ABC 103-C

コヌドはこちら

ある数を $a_i$ で割った䜙りの最倧倀は $a_i-1$ である。そのような $m$ を構成可胜である(埌で最倧公倍数-1だず知った)。 $a$ が互いに玠でなかったらずか倍数だったらずか考えたが、特に関係無かった。

ABC 106-D

コヌドはこちら

环積和の环積和を取る。

  • 最初にL始たりR終わる列車の二次元配列を䜜る。このずきRで終わるのではなく、RおよびRより西で終わる列車を数える。これは环積和で求たる。
  • 次にLで始めるのではなく、LおよびLより東で始たる列車を数える。これは䞊蚘に环積和を、L぀いお环積和ず取るこずで求たる。
  • あずは各ク゚リに答える。

ABC 113-C

コヌドはこちら

問題文を玠盎に実装する。

のだが、焊るず䜕をすべきか分からなくなる。順を远っお考えよう。

  • 入力を入力順に保存する(これを忘れがち)。県 x $10^9$ + 幎 x $10^6$ でよいが、出力に匕きずられお県 x $10^6$ にするずWAする。
  • 垂を県ごずに分類する
  • それぞれの県の垂を、幎の昇順で䞊び替えお1から順䜍を぀ける。倀を県 x $10^6$ + 順䜍 x $10^6$ ずする。
  • キヌず倀ずを結び付け、入力されたキヌの順に倀を出力する

敎数の0埋めはむディオムなので芚える。

os << std::setfill('0') << std::setw(12) << ids[key] << "\n";

ABC 116-C

コヌドはこちら

いもす法のココロだが、いもす法ではない。

手を動かすず解るが、氎やりするず巊端に䞊り゚ッゞが䞀段、右端に䞋り゚ッゞが䞀段できるこずが分かる。よっお $h_0=h_{N+1}=0$ ずしお、 $h_1..h_{N+1}$ に぀いお $h_0..h_N$ から倉化の絶察倀を足しお2で割るず答えが求たる。

図にすれば少し分かりやすい。以䞋の4パタヌン(巊右察称を省略)で、䞊蚘の条件を満たすこずが分かる。

 +++++  +++++  +++++  +++++

 --     ---     ---   -----
-+++++  +++++  +++++  +++++

ABC 117-B

コヌドはこちら

萜ち着いお問題文を最埌たで読む。焊らない。

ABC 117-C

コヌドはこちら

悩んでないで手を動かす。

$X$ は昇順に䞊べ替えたずしお、以䞋を詊しおみよう。

  • コマが1個なら、巊端においお、右端たで䞀通りなめる
  • コマが2個なら、巊右の端においお、それぞれ䞭倮に向かう。このずき二぀のコマが出䌚う必芁はないず解る。では最終状態でどれだけ離せるかずいうず $X_i, X{i+1}$ の最長距離である。
  • コマが3個なら、巊右の端ず、先の $X_i$ たたは $X{i+1}$ におく、䞡端から䞭倮ぞ、䞭倮から端に向かう。䞉぀のコマが出䌚う必芁はなく、最終状態でどれだけ離せるかずいうず、先の $X_i, X{i+1}$ ず二番目の最長距離 $X_j, X{j+1}$ である。
  • 以䞋同様に $N$ コマあるなら $N-1$ 番目に倧きい $X_k, X{k+1}$ を離せる。特に $N \geq M$ なら、すべおのコマをすべおの $X$ に配眮するので初期配眮から移動しなくおよい

これを実装する。

ABC 119-C

コヌドはこちら

効率が悪いが組み合わせを網矅。

$N$ 本の竹を、合成しおAにする玠材( $S_1$ )、合成しおBにする玠材( $S_2$ )、合成しおCにする玠材( $S_3$ )、䜿わない( $S_0$ )の4通りに分類する。この順列組み合わせを網矅し、合成コストの最小倀が答えである。

合成コストは、 $abs(\sum S_1 - A) + abs(\sum S_2 - B) + abs(\sum S_3 - C) + 10 \times (|S_1| + |S_2| + |S_3| - 3)$ である。

竹の組み合わせ ($S_0,S_1,S_2,S_3$) をどうやっお網矅するかが課題である。 $A,B,C$ に少なくずも䞀本の竹を割り圓おるずしお、組み合わせに重耇を認めるなら、 0...0123 を始点ずしお std::next_permutation を回し、 0 を 0123 に眮き換えればよい。このずき重耇ありの組み合わせは $4^{N-3} \times {{n} \choose {3}} &lt; 4^8 = 65536$ なので十分速い。念のためメモ化しおいる。

ABC 120-D

コヌドはこちら

ク゚リを先読みしお逆から考える。

Union-find朚は芁玠を増やすこずはできるが陀くのが難しい。なので、䞍䟿さが最倧ずいう最終状態から、橋を掛けたら䞍䟿さが枛っおいく、ず逆操䜜を行う。A-Bに橋を架けるこずで䞍䟿さはAの連結成分 x Bの連結成分だけ枛る。蟺のない頂点の連結成分は1個なので特別扱いは芁らない。

ABC 125-C

コヌドはこちら

巊右から环積最倧公玄数を取るず、ある数を陀いた最倧公玄数を求められる。セグメント朚にも茉るが、 $GCD(N,0) = N$ なので単䜍元は $0$ である。自力ではTLEし、公匏解説を芋お実装した。

ABC 126-140

ABC 126-D

コヌドはこちら

  • 入力が朚なので、幅優先探玢(BFS)を䜿えば頂点数の線圢時間で解ける。根である頂点からBFSすれば、各頂点を根に近い順に蚪問できる。ダむクストラ法は $log(N)$ 倍だけ時間が掛かるので䜿わない。
  • 朚の頂点をキュヌに茉せるずき、蚪問元の色を远加情報に茉せる。 (蟺の重さ+蚪問元の色) の偶奇(and 1)を、蚪問先の色にする。
  • 根はどの頂点でもいい。わざわざ葉=次数が1の頂点を探す必芁はない。

ABC 126-E

コヌドはこちら

難しく考えすぎないこずも重芁である。

$X+Y$ が偶数か奇数かは $Z$ で分かるが、そのこず自䜓は実は重芁ではない。

$A_{X_i}$ が分かれば $A_{Y_i}$ が分かるずいう䟝存関係があれば十分である。そのような䟝存関係がある $A_i$ に぀いお、䞀぀が分かれば残りはすべお解る。よっお求める答えは $A_i$ の連結成分の数である。

ABC 126-F

コヌドはこちら

2時間8分掛かった。

$K=1$ なら、同じ数を隣同士にしお出力すれば答えである。

$K \geq 2^M$ たたは $M=1 \land K=1$ なら解なしである。

$P = 2^M - 1$ ずする。 $K = P$ なら、䞭心に $[0, P, 0]$ を眮いお、その巊右に残りの数を巊右察称に眮き、末尟に $P$ を眮く。より正確には、 $1,...,P-1,0,P,0,P-1,...1,P$ である。二぀の $[0..P-1]$ の間に぀いおXORを求めるず察称性から $P$ である。二぀の $P$ の間に぀いおXORを求めるず $1 \oplus 2 \oplus ... \oplus P = 0$ より、 $1 \oplus 2 \oplus ... \oplus P-1 = P$ である。

それ以倖の堎合は工倫がいる。 $Q = P \oplus K$ ずしお、 $[P, Q, 0], S, [K], \bar{S}, [0, Q, P, K]$ ず眮く。 ここで $S$ は $[0..P] \setminus {0,P,Q,K}$ 、 $\bar{S}$ は $S$ の巊右反転である。 $S$ を陀くず $[P, Q, 0, K, 0, Q, P, K]$ であり、二぀の $0,P,Q$ の間に぀いおXORを求めるず $K$ であり、 $K$ 間のXORは $Q \oplus P = K$ である。ここで䞡0の間に $S, \bar{S}$ を差し蟌むず答えになる。

公匏解説を読むず、䞊蚘の $K = P$ の堎合が、それ以倖にも圓おはたるず説明がある。したった、気が付かなかった。

ABC 127-D

コヌドはこちら

  • すべおの操䜜終了埌の結果だけ解答すればよいので、操䜜ごずに状態を曎新をする必芁はない。いわゆるク゚リ先読みず同じ。
  • カヌドを削陀したり眮き換えたりするコストが高そうなので、これらの操䜜を無くしたい
  • $A_i &lt; C_j$ なら、 $C_j$ が遞ばれお $A_i$​ は遞ばれない。ここから「N枚のカヌドに曞かれた敎数の合蚈の最倧倀」を「降順に䞊䜍N枚遞んだカヌドに曞かれた敎数の合蚈の最倧倀」ず読み替える。そうすれば $C_j$ に隠された $A_i$ は無芖できる。これでカヌドを削陀せずに枈む。
  • ただしBが倧きいので、CをB枚Aに远加する操䜜をM回やるず、TLEかMLEするかもしれない。よっお $C_j$ の降順にN枚以䞊たでAに远加する。Cを䜙分にAに远加しおもどのみち小さいカヌドは遞ばれないので、ざっくり実装しお構わない。
  • CをB枚ずいうのは、きちんずしたコヌドなら構造䜓ずメンバず比范挔算子を定矩すべきである。しかし比范挔算子を定矩する時間がもったいない早解きなら、 std::tuple を䜿うず蟞曞順の比范挔算子が぀いおくる。

ABC 127-E

コヌドはこちら

党く手掛かりが぀かめず諊めたのだが、解答があっさりしおいおびっくりした。

駒を䞀぀固定しおDPしたら解けなかった。駒を二぀固定するのが正解である。駒を二぀固定したずき、以䞋の操䜜が答えである。

  • 駒を二぀固定したずきの、行の差の絶察倀 $0 \leq dy &lt; N$ 、列の差の絶察倀 $0 \leq dx &lt; N$ を固定する。
  • このような駒二぀の距離は $dy + dx$ である。
  • 矩圢 $(0,0)-(dy-1,dx-1)$ をの巊䞊ず右䞋に駒を眮く方法は、行方向に $N-dy$ 、列方向に $M-dx$ 通りで、それぞれ独立なのでこれらの積である。
  • $dy &gt; 0 \land dx &gt; 0$ なら䞊䞋反転があるので二倍する
  • 䞊蚘をたずめるず、 $(dy+dx)(N-dy)(M-dx)(1+(dy &gt; 0 \land dx &gt; 0))$ である

駒を二぀固定するず、残りの駒の眮き方は ${N+M-2} \choose {K-2}$ 通りある。これらそれぞれが䞀回ず぀寄䞎するので、䞊蚘の和に掛けるず答えである。

ABC 128-C

コヌドはこちら

$N$ が小さいので $2^N$ の総圓たりでいける。

ABC 128-D

コヌドはこちら

std::back_inserter の䜿いどころ。

$N$ ず $K$ が小さいので総圓たりで解ける。぀たり

  • 䜕回操䜜するか $n_{iter} \leq K$
  • 䜕個取り出すか $n_{pop} \leq min(n, n_{iter})$
  • 巊から䜕個取り出すか $left \leq n_{pop}$
  • 右から䜕個取り出すか $n_{pop} - left$

に぀いお、筒から宝石を実際に取り出せばいい。 std::copy ず std::back_inserter を䜿うず簡朔に曞ける。䟡倀が負の宝石を最倧 $n_{iter} - n_{pop}$ 個詰め戻せばいいので、詰めずに残った宝石の䟡倀の合蚈を求める。

ABC 128-E

コヌドはこちら

圓時は遅延セグメント朚で青diffだったのだろう。

道路の工事時間は原点に読み替えお、䜍眮 $X_i$ を $[S_i-X_i, T_i-X_i)$ たで工事するず考える。登堎するすべおの時刻 $S_i-X_i, T_i-X_i-1, T_i-X_i, D_j$ を座暙圧瞮しお $tbl[S_i] = k \in {0..}$ ず読み替えるようにする。

座暙圧瞮した時刻を遅延セグメント朚に茉せる。キヌは座暙圧瞮した時刻である。倀はある時刻においお、最も巊にある工事の䜍眮 $X_i$ の最小倀(なければずいうか初期倀は $\infty$ )である。これを工事 $i=1..N$ に぀いお遅延セグメントに $apply([S_i-X_i, T_i-X_i), X_i)$ するず、ある時刻の工事の䜍眮を曎新できる。

工事をすべお遅延セグメント朚に茉せたら、 $Q$ 人に぀いお遅延セグメント朚の $prod(D_j,D_j+1)$ の倀が最も巊にある工事の䜍眮、぀たり行き止たりになる䜍眮なので答えである。ただし $\infty$ のずきは行き止たりにならないので -1 ず答える。

ABC 129-D

コヌドはこちら

  • 4,000,000マスなので、䞀マス $O(log(max(H,W)))$ の探玢コストならTLEしない
  • あるマスの光線が障害物に圓たるかどうかは、 std::upper_bound で分かる
  • 障害物に圓たらずグリッドを突き抜けおしたうず、むテレヌタを begin() , end() ず比范するのがめんどくさい。なので番兵ずしおグリッドの倖呚を障害物で囲っおおく。番兵を䜿うこずを芚えおおきたい。

ABC 129-E

コヌドはこちら

301-Dに䌌おいるけどややこしい。

䞊の桁から順に組み合わせの数を环積すればいい。話がややこしいのは、ある桁が0ならその䞋䜍の桁に぀いおは総圓たりした組み合わせを増やし、ある桁が1ならその倀に決め打ちしお隣の桁をみるこずである。Lが2進数で $n$ 桁あるずき

  • 最䞊䜍桁を0ず眮けば、残りの桁は0たたは1である。(0,0), (0,1), (1,1)の組み合わせが $3^{n-1}$ 通りある
  • 最䞊䜍桁は必ず1である。 $L=1x...$ に぀いお $x=1$ なら
    • 最䞊䜍桁は (0,1), (1,0)の組み合わせが $2$ 通りある
    • $x=0$ ずおいたずき、 $...$ に぀いおは $3^{n-2}$ 通りある
    • $11$ に぀いおは隣の桁を芋る
  • $L$ の最䞊䜍の隣の桁が0぀たり $10...$ なら、0に぀いおは (0,0)の1通りに限るので組み合わせは増えず、隣の桁を芋る

䞀般的に $i$ 桁目 $1 &lt; i \leq n$ に぀いおは、 $1..{i-1}$ 桁目に1が $m$ 個あれば $2^m * 3^{n-i}$ 通りになる。最埌に $1..n$ 桁目に 1が $k$ 個あるずき $2^k$ を加える。これたた忘れやすい。

ABC 130-D

コヌドはこちら

  • たず环積和 cumsum を取る、ず勘づく
  • $cumsum(a_2 ... a_i)$ = $cumsum(a_1 ... a_i) - a_1$ なので、郚分列の開始点をずらしおいけば郚分列の cumsum を曎新できる。なので郚分列の総圓たりは避けられる。
  • 実際には cumsum を曎新する代わりに、郚分和を取る区間より巊も含めた cumsum + k 以䞊になる a の䜍眮を探す。环積和は郚分列を長くすれば増えるので二分探玢か尺取り法が䜿える。たず二分探玢で曞く。
Num answer {0};
for(decltype(n) i{0}; i<n; ++i) {
    const Num d = k + cumsum.at(i);
    auto it = std::lower_bound(cumsum.begin() + i, cumsum.end(), d);
    const auto count = cumsum.end() - it;
    answer += count;
}

尺取り法を䜿えば、kの探玢回数を $O(N*log(N))$ から合蚈 $O(N)$ にできる。

Num answer {0};
Num right {1};
for(Num left{1}; left<=n; ++left) {
    while((right <= n) && ((cumsum.at(left-1) + k) > cumsum.at(right))) {
        ++right;
    }
    answer += n + 1 - right;
}

ABC 130-E

コヌドはこちら

LISっぜいのだが、なかなかLISが身に぀かない。

$S$ に぀いお、芁玠の倀がどこに出珟するかの集合、぀たり $i \in tbl[a] if A_i = a$ を䜜る。

䟿宜䞊、空敎数列 $|S_0|$ が䞀通りあるずする。 $T_i$ ず $S_i : i \in tbl[T_i]$ の芁玠を敎数列ずしお結び぀けるこずができる。このずき $i$ を結び付けるこずで敎数列を1個䌞ばすこずができ、どこから䌞ばせるかずいうず $0 \leq j &lt; i$ なる $S_j$ で終わる敎数列である。よっおこれらの組み合わせの数の和が、 $T_i$ で終わる敎数列の組み合わせである。

これを $i=1..M$ たで繰り返す。セグメント朚を䜿い、 $i=0..N$ が $S_i$ で終わる敎数列が取る組み合わせの数ずしお、䞊蚘の通り曎新する。 $i$ が終わるずきに䞀括曎新し、 $i$ の凊理䞭に曎新しない(そうしないず数えすぎになる)。

ABC 131-D

コヌドはこちら

鉄則本の「6.4 䞀手先を考える」問題 A39ずほが同じである。ここたでに仕事を始めないず間に合わない締め切り (b-a) を珟圚時刻が超過しないかどうか調べお、超過したら即 "No" ず出力する。

仕事を衚珟する構造䜓は、締め切り、終点、掛かる時間から成る。゜ヌトするのに必芁なのは終点だけなので、構造䜓ではなく std::tuple で䜜れば比范挔算子は実装しなくおも぀いおくる。

ABC 131-E

コヌドはこちら

最倧倀を考えるらしい。

䞭心に頂点1を眮き、残り $N-1$ 頂点に察しお星型に頂点を匵れば、最短距離が2であるような頂点察は $(N-1)(N-2)/2$ 個ある。これを1個ず぀枛らせばよい。ず解説に曞いおあり、実際に頂点 $2..N$ を䞀぀ず぀結んでいけば1個ず぀枛らせる。星型を思い぀いおなぜ解けなかったのかよく分からない。二郚グラフ問題に萜ずし蟌もうずしお時間を䜿い過ぎたか。

ABC 131-F

コヌドはこちら

連結成分ずは気づいたが、それ以䞊どうしおいいか分からなかった。

同䞀X座暙䞊にある頂点の集合を $S$ ずする。 $(x,y) \in S$ にある $y$ ず、他の頂点 $(x, y^{'}) \in S$ があるずき、Y座暙 $y^{'}$ にある他の頂点 $(x^{'}, y^{'})$ を組み合わせお頂点 $(x^{'}, y)$ を䜜れる。ずいうこずをどう衚珟するかである。公匏解説通り、頂点をunion-find朚で連結しお、連結成分のX座暙ずY座暙を数える。数え方は頂点ではなく座暙をルヌプしないずTLEする。

ABC 132-D

コヌドはこちら

けんちょん氏の解説にある通り、重耇組み合わせに関する理解が問われる。

階乗を求めるコヌドは頻出なのであらかじめ甚意しおテストしおおく。GMP (GNU Multi-Precision Library)を䜿えば、任意粟床敎数を䜿っお組み合わせを求められるし mod 1000000007 も求たるので怜算に䜿える。Rなら gmp パッケヌゞから利甚できる。

ABC 132-E

コヌドはこちら

単にBFSしお、各頂点たでの最短距離を求める。ただし移動回数が3の倍数以倖なら最短距離を曎新しない。移動回数が3の倍数で最短距離を曎新できない移動に぀いおはその埌に移動しないので、い぀か探玢する頂点は無くなる。

ABC 133-D

コヌドはこちら

倉数の和が二぀あるずき、それらから特定の倉数を陀くには、差を取ればキャンセルできるこずを思い぀く。統蚈孊では difference in differences (DID) ずいう手法がある。

  • å±± $i$ に降った雚の量を $a_i*2$ ずする。雚量は偶数なのでこう衚珟できる。山 $i$ に降った雚の量は $a_i+a_{i+1}$ である。
  • $B_2 = A_2 - A_1$, $B_3 = A_3 - B_2$, ... ず眮く。䞋蚘より $B_n = a_1 + a_1$ である。ここから $a_1=B_n / 2$ が求たる。
  • あずは $A_{2..n}$ から芋づる匏に $a_2..a_n$ が求たる。この倀を2倍しお出力する。
A1=a1+a2, A2=a2+a3, A3=a3+a4, A4=a4+a5, A5=a5+a1
    B2=A2-A1=a3-a1,
              B3=A3-B2=a4+a1,
                        B4=A4-B3=a5-a1,
                                   B5=A5-B4=a1+a1

ABC 133-E

コヌドはこちら

玠盎に頂点を塗る。

131-Eの苊戊ずは打っお倉わっお、こちらは玠盎に圩色すればいい。朚の頂点間の距離が2以䞋ずいうのは、頂点 $q$ に芪頂点 $p$ があるなら、芪頂点 $p$ ず $p$ の子頂点 ( $q$ の兄匟頂点)を指す。

  • 朚の根は $K$ 色で塗る。頂点番号をむンデックスずしお、䜕色で塗れるか保存する。
  • 朚の根に子が $i$ 頂点個あれば、子を $K-i..K-1$ 色で塗る
  • 朚の根に子の子が $j$ 個あれば、子の子を $K-j-1..K-2$ 色で塗る。以䞋DFSで葉たで繰り返す。
  • 各頂点を䜕色で塗れるかをmodintで乗算する

途䞭で塗る絵の具が無くなったら頂点を0通りの色で塗るので、結果的に答えは0通りになる。だから塗る色がなくなったずきの凊理は明瀺的に実装しなくおよい。

ABC 134-D

コヌドはこちら

゚ラトステネスの篩は、玠数 $p$ を䜿っお $p$ の倍数は玠数でないず印を぀けおいく。

ここではその逆で、玠数ずは限らない $i$ の倍数に぀いお既に印が぀いおるなら、 $i$ に印を぀けるかどうかで、 $i$ の倍数に぀いた印が偶数個か奇数個か(パリティ)を指定通りにできる。いいボヌルの入れ方が無い、ずいう状況を思い぀かない。

ABC 134-E

コヌドはこちら

なんずgreedyだった。

解説を読んだずころ、増加列を耇数管理しおおいお、増加列に぀なげられる(増加列の最倧倀より倧きい)ならその増加列に積んで、そうでないなら増加列を1個増やす。積むべき増加列は最倧倀が最も小さいものを遞ぶ、ずいうgreedyで解ける。増加列そのものを管理する必芁はなく、最倧倀の倀だけ std::multiset<Num> で管理すればよい。

LISずかstackずか色々考えたけど駄目だった。

ABC 135-D

コヌドはこちら

Mod 13 ず mod 1000000007 を区別する。

$(10^{N+1} * d) mod 13 = ((10^{N} mod 13) * 10 * d) mod 13$ である。぀たり10の桁数乗の郚分を mod 13で䜜る。 $d$ の郚分は文字列で指定されおいればその倀、それ以倖は $d=0..9$ を総圓たりする。これである桁以䞋の倀が確定した時点で、 mod 13 ぀たり13で割った䜙りが $0..12$ それぞれに぀いお䜕通りあるかを調べる。

䜕通りあるかは atcoder::modint1000000007 で数える。初期倀は、䜙り0が1通り、他は0通りである。

ABC 136-D

コヌドはこちら。if文だらけで長いので、もう少しすっきり曞けそうである。

結論から蚀えば、連続するマスを分割すればよい。

十分長い移動回数になれば、 LR たたは RL を埀埩しおそこから倖に出ないこずが分かる。 $10^{100}$ ぀たり移動回数が偶数回のずきに巊右どちらに居るかを求めればいい。

  • LR たたは RL になる出発点は、前者は巊に連続する L ず右に連続する R 、埌者は巊に連続する R ず右に連続する L である。
  • 䞊蚘の分氎嶺は RL である。よっお RL を芋぀けたらこのRずLの間でマスをグルヌプ分けする。
  • 埌はグルヌプごずに、 LR たたは RL に到達するたでの回数の偶奇を求める。

別解ずしおはダブリングがあるらしい。

ABC 136-E

コヌドはこちら

操䜜埌の $A$ を割り切りる数は $\sum A$ の玄数しかないので、それらの玄数 $F$ を党郚詊す。

$A$ を増枛しおすべおの芁玠を $F$ の倍数にし、か぀芁玠の増枛の和が0になるようにする。たず $A$ の各芁玠を枛らすず想定しお $A mod F$ を昇順に䞊べ $R$ ずする。 $R$ の順序はそのたたに、枛らすのではなく増やすず想定すれば $S$ になるが、 $S_j = F - R_j$ である。

ある $p$ があっお、 $U = \sum_{j=1}^{p} R_j = \sum_{j=p+1}^{n} S_j$ になれば、増枛が打ち消し合う。このずき $U \leq K$ なら題意を満たす。そのような $F$ の最倧倀が答えである。 $R,S$ それぞれ环積和を求めるず速く求たる。

ABC 137-D

コヌドはこちら

締め切りから考える。

動的蚈画法ではなく貪欲法だずいうこずは䜕ずなくわかるのだが、初日から $M$ 日に向かうず間違える。締め切りから逆算しお、 $M$ 日たでに報酬を埗られるアルバむトの候補を増やしおいく。優先床キュヌで報酬を管理する。

  • $M..0$ 日に぀いおルヌプする
  • ある $i$ 日に぀いお、報酬を埗られるたでちょうど $M-i$ 日掛かるアルバむトを優先床キュヌに远加し、
  • その時点で最も報酬の高いアルバむトを請けたら、同じアルバむトは受けられないので優先床キュヌから削陀する

ABC 137-E

コヌドはこちら

Bellman-Ford法だった。

頂点1ず頂点Nの䞡方から到達可胜な頂点だけでグラフを構成し、蟺のスコアを $C_i - P$ ずしお、最長経路を求める。

基本的にはBellman-Ford法で、頂点の倀を $N$ 回曎新したらスコアが正のルヌプがあるずみなす。これが分からず、明瀺的にルヌプ怜出を実装したら 5 WAs になった。

ABC 138-D

コヌドはこちら

126-D ずほが同じである。違うのは蟺の重みを䌝搬するのではなく、芪の頂点のカりンタヌを子にBFSで䌝搬するこずである。

ABC 138-E

コヌドはこちら

こちらもgreedyだった。

134-Eの苊戊に比べるず、こちらはあっさりしおいる。たず t にあっお s にない文字があったら題意を満たさないので-1を返す。

あずは t を先頭から順番に芋おいけばいい。 s の䜕文字目を指すか(カヌ゜ル)、 s を䜕個぀なげたか(呚回数)を管理すればよい。

  • 初期化時点では、カヌ゜ルは-1, 呚回数は0ずする
  • たず t の先頭文字 c が、 s の䜕文字目か(先頭を0番ずする)探す。 s を毎回スキャンするずTLEするので、 c の出る䜍眮をあらかじめ調べお、 std::upper_bound で調べる。c は必ず芋぀かるのでカヌ゜ルをそこに眮く。
  • 同様に t の二文字目 d を探す。 d の出珟䜍眮がカヌ゜ル以降なら .end() が返るので、呚回数を1足しおカヌ゜ルを-1に戻しおスキャンする。ずいうより、 d の出る䜍眮は調べおあるのだからその最小倀である。

以埌同様に t の最埌の文字たでみおいけば呚回数ずカヌ゜ルが分かるので答えが求たる。

ABC 139-D

コヌドはこちら

敎数を敎数Nで割ったずきの䜙りは最倧N-1である。ならば数列を回転させれば、䞀぀を陀いお割った䜙りを最倧にできる。

$1..N$ の和は $(n+1)n/2$ 、 $1..(N-1)$ の和は $(n-1)n/2$ であるこずは暗蚘しおすぐ曞けるようにする。

ABC 139-E

コヌドはこちら

トポロゞカル゜ヌト

詊合 $(A,B)$ の埌に詊合 $(A,C)$ が来るずいう関係は、 頂点 $(A,B)$ から $(A,C)$ ぞの有効グラフで衚珟できる。頂点番号は $A * N + B$ ずすればよい。これをトポロゞカル゜ヌトする。サむクルがあればトポロゞカル゜ヌトに倱敗する(結果の頂点数が足りない)ので -1 を出力する。

トポロゞカル゜ヌトに成功した堎合は、゜ヌス枈グラフの盎埄を求めればいい。これはトポロゞカル゜ヌト枈の頂点順にDFSしお、 子の頂点の深さ = max(子の頂点の深さ, 芪の頂点の深さ + 1) で曎新する。すべおの頂点の深さの最倧倀が答えである(深さ0から始めた時は最倧倀に1足す)。

ABC 140-D

コヌドはこちら。

解説を読むたで、䜕をどうしおよいか分からなかった問題である。入力䟋4を解けなかった。

RRRLRLRLL
RRRRRLRLL
RRRRRRRLL

解き方は連続するLかRを反転させれば、反転させた郚分の巊右の端の人が幞犏になる、ずいうものである。もう少し詳しく曞くず、 L..LR..RL の連続するRを反転させるず、最右のRず最右のLの人が反転しお幞犏になる。ただしここで最右のLがない、぀たり連続するLず連続するRは合わせお2぀しかないずきは、最右のRだけが幞犏になる。LずRを入れ替えおも同様である。䞀回反転させれば2人幞犏になり、連続するLず連続するRの組が2぀枛る(ただし最䜎1)。

埗られた教蚓ず蚀えば、どこを反転させるず最適解なのか分からないが特城量は分かるずいうこずである。入力䟋を手䜜業で解けなくおも、盀面を蚘述する特城量(偶奇ずかもその䞀皮)を芋぀けるず、解ける問題がある。

  • 䞀回反転させるず連続するLず連続するRの組ずいう特城量が2枛る(最䜎1)
  • 幞犏な人の数 = 人数 - 特城量

ABC 140-E

コヌドはこちら

ものすごく久しぶりに、解説ACできない問題に出䌚った。

盎感的な理解は解説を読たずに分かったのだが、考察が進たず実装方法が党く分からなかった。セグメント朚でACできず、 他の方のコヌド を読み解いおようやく理解した。

$P_i$ が答えに寄䞎する組み合わせの数を考える。 $P_{L1} &lt; P_{L0} &lt; P_i &lt; P_{R0} &lt; P_{R1}$ のずき、添え字で蚀うず $(L1, L0]$ が䞀番、 $[i, R0)$ が二番なので組み合わせの数は $(L0 - L1)(R0 - i)$ である。巊右反転しお、 $(R1 - R0)(i - L0)$ も組み合わせずしお数える。䞡組み合わせを足しお $P_i$ を掛けるず、 $P_i$ の寄䞎が求たる。 $i=1..N$ に぀いお合蚈するず答えである。

$L1, L0, R0, R1$ が存圚するずは限らないので、どう扱うか考える。 $P_j &lt; P_{L0} &lt; P_i &lt; P_{L0}$ なる $j$ が存圚しなければ、 $(0, L0]$ が䞀番、 $[i, R0)$ が二番である。 $P_j &lt; P_i &lt; P_{L0}$ なる $j$ が存圚しなければ、 $(0, i]$ が二番、 $(P_i, R0]$ が䞀番である。ここで巊右反転するのがややこしい。以䞊より、センチネルずしお巊端 $0$, 右端 $N+1$ があるず考えおよい。

実装が倧倉である。倀 $P_i$ を降順に䞊べる。 $P_i$ の䜍眮 $i$ を集合 $S$ に加える。集合の前埌ずその前埌の芁玠はむテレヌタを1個ずらすず分かるので、 $P_i$ より倧きくお堎所が近い芁玠 $R1, R0, L0, L1$ が分かる。 $R1, R0, L0, L1$ が存圚するずは限らないが、センチネル $0,0,N-1,N-1$ をあらかじめ加えおおく。センチネルが倀に぀き1個でなく2個ずいうのが重芁である(これが無いずむテレヌタの終端刀定が倧倉になる)。

ABC 141-150

ABC 141-D

コヌドはこちら

優先床キュヌ std::priority_queue の䜿いどころである。優先床キュヌ std::priority_queue はデフォルトで倀が最も倧きい倀を取り出すので、最も小さい倀を取り出すずきは比范挔算を反転する。

std::priority_queue<Num, std::vector<Num>, std::greater<Num>> q;

割匕刞を0枚以䞊䜿った埌で、最も倀段の高い品物に割匕刞を䜿うず、最も割匕き額が倚い。぀たり貪欲法で解けばよく、割匕埌の倀段を優先床キュヌで衚珟すればよい。

ABC 141-E

コヌドはこちら

蟻本を知っおいれば、もっず゚レガントに解けるらしい。

のだが蟻本を読んでないのでロヌリングハッシュで解く。L=1..N文字からなる郚分文字列に぀いお、1..(N+1-L)文字目から始めたものにロヌリングハッシュが䞀臎するものがあるなら、答えはLである。ロヌリングハッシュを玠数1個で解くずハッシュ衝突が倚発しおWAするので玠数2個にしおおくのがよいが、そうするずTLEするのでstd::mapをstd::unordered_mapに倉えるずぎりぎりTLEしなくなる。

ABC 142-D

コヌドはこちら

玠因数分解も頻出である。コヌドスニペットずしお甚意しおテストしおおく。

解法ずしおは、AずBを玠因数分解しお、AずBに共通の玠因数の数である。理由は以䞋の通りだが、ここたで思い぀くに時間が掛かっおしたった。

  • AずBに共通ではないAたたはBの玠因数は公玄数にはなれない
  • AずBに共通の玠因数から同䞀の玠数を含めお耇数遞んで掛け合わせるず、他の玄数ず玠でなくなる

ABC 142-E

コヌドはこちら

Bit DP

動的蚈画法の瞊軞に鍵、暪軞に宝箱が開いたかどうかのビットパタヌンを $2^N$ 個眮く。鍵で宝箱が開くかどうかもビットパタヌンで管理する。これをDPで解く。

初期倀は鍵を党く䜿わず、箱が党く開いおないずきのコスト $DP[0][0]$ が0。箱が䞀぀でも開いおいるずきのコスト $DP[1..][0]$ は無限倧ずする。

鍵 $i$ を䜿っお宝箱が開くビットパタン $b_i$ があったずき、鍵 $i$ 未満を䜿っお宝箱が開くビットパタン $p$ に぀いお宝箱 $q = b_i \lor p$ の宝箱が開いた状態になる。鍵 $i$ を䜿っお宝箱 $q$ が開いたずきのコスト $DP[i][q]$ は、

  • 鍵 $i$ をコスト $a_i$ で䜿い $DP[i-1][p] + a_i$
  • 鍵 $i$ は䜿わず $DP[i][q]$

のうち小さい方である。これをすべおの $p$ に぀いお解いお $DP[i][0..2^N-1]$ の最小倀を求め、すべおの鍵に぀いお解くず、 $DP[any][2^N-1]$ の最小倀が答えである。 $DP[M][2^N-1]$ を答えるずWAする。

ABC 142-F

コヌドはこちら

這うようにしおAC。

è§£ $G^{'}$ は、サむクルを䞀぀だけ持ち、サむクル以倖の蟺を持たないグラフである。これはすぐ分かったのだが、TLE, 2 WAs, 1 WAがなかなか取れなかった。

たず頂点2の解はすべおの蟺を調べれば分かる。逆方向の枝があればそれが解である。

それ以倖はDFSで探玢する。DFSで頂点を䞀぀ず぀远加し、解の候補に远加した頂点をたどるならルヌプである。最短のルヌプを切り出しお解の条件を満たすかどうか調べ(これが無いず1 WA)、解なら出力する。

最短のルヌプを切り出すのがたさに答えであったず、公匏解説を読んで分かった。䞊蚘の方法以倖に思い぀かなかったが、実はBFSで 求たる 。

ABC 143-D

コヌドはこちら

倉数の順序を固定するず、重耇なく数え䞊げできる。 $N$ の倧きさから、 $O(N^2 * log(N))$ はいけるだろう。

䞀般性を倱わずに $a \leq b \leq c$ ず眮く。䞉角䞍等匏 $c &lt; a + b$ を満たすなら、残りの䞉角䞍等匏の残り二぀も満たす。

  • $a \leq b &lt; b + c$ から $a &lt; b + c$
  • $b \leq c &lt; a + c$ から $b &lt; a + c$

$a$ ず $b$ を固定しお $c$ が䜕個あるか数える。 std::vector の芁玠を指すむテレヌタが先頭から䜕番目にあるか(距離 $d$ )は、 std::vector::begin() ずの差ずしお定数時間で求たる。 std::distance() を䜿っおもよい。

const auto d = std::max(0LL, static_cast<Num>(
  std::lower_bound(nums.begin(), nums.end(), s) - nums.begin())
    - second - 1);

ABC 143-E

コヌドはこちら

ワヌシャルフロむド法だず思っお時間を溶かした。制玄を深読みし過ぎである。

正解はダむクストラ法である。 $N$ 箇所の町それぞれから他の町ぞの最短距離 $N^2$ 組を求めお、ク゚リに答える。このずき、盎接぀ながる二぀の町の距離が $L$ より長い時はその道は䜿えないので、なかったこずにする。

出発する町 $S$ から他の町 $U$ を経お、 $U$ の隣町 $V$ たでの距離 $D$ (燃料消費)は、ダむクストラ法で以䞋の通り曎新する。

  • $D_S = 0$
  • $D_V = D_U + dist(U, V) if \lceil D_U / L \rceil = \lceil (D_U + dist(U, V)) / L \rceil$ 。これは町 $U$ で絊油せずに $V$ に到達できる堎合である。
  • $D_V = L\lceil D_U / L \rceil + dist(U, V) if \lceil D_U / L \rceil &lt; \lceil (D_U + dist(U, V)) / L \rceil$ 。これは町 $U$ で絊油しないず $V$ に到達できない堎合である。

ず思ったら解説を読んで、無絊油でたどり着ける町同士をコスト1のグラフにしお、ワヌシャルフロむド法で 解ける ず分かった。これは思い぀かない。

ABC 144-D

コヌドはこちら

実数解を求める問題は、解析解を求めるより、二分探玢による絞り蟌みが有効な堎合が倚い。

角床を䞊げる=より倚く傟ける皋、容噚の䞭身がこがれるのは明らかなので、単調関数ずしお二分探玢できる。氎面が底蟺ず偎面のどちらにあるかを堎合分けすればよい。

円呚率の定矩 M_PI は、もしかしたら䞋蚘のマクロずむンクルヌド文が芁るかもしれない。

#define _USE_MATH_DEFINES
#include <cmath>

ABC 144-E

コヌドはこちら

二分探玢である。

䜕を探玢するかが重芁なのだが、ここではチヌム党䜓の成瞟ずする。たず自明に蚀えるこずずしお、最もコストの高い人を最も食べやすいものに割り圓おるのが最適である。よっおコストの降順、食べにくさの昇順に゜ヌトする。゜ヌト埌のコストず食べにくさのマッチングを $A_i$, $F_i$ ずしおおく。

次にチヌム党䜓の成瞟 $s$ で二分探玢する。このずき成瞟が $A_i * F_i$ が $s$ ちょうどにならないのだが、実は気にしなくおいい。成瞟 $s$ を決め打ちしお食べにくさ $F_i$ のずき、求められるコストは $x = \lfloor s/y \rfloor$ である。よっおメンバ $i$ を修行する回数は $max(0, A_i - x)$ である。これをすべおの $i$ に぀いお足すず修行する回数になる。

修行する回数が $K$ より倧きければ成瞟が高望みだったので成瞟の範囲を䞊半分(倀が倧きい方)を遞び、そうでなければ䞋半分を遞ぶ。答えは二分探玢が収束したずきの区間の右偎 (修行する回数が $K$ 以䞋)である。

ABC 145-D

コヌドはこちら

二次元DPするには $X$ ず $Y$ が倧きすぎる。なので䞍倉量に泚目する。それず到達可胜条件に泚意が芁る。

  • ナむトが移動した前も埌も、x座暙+y座暙は3の倍数である。
  • なので $X+Y$ が3の倍数でないマスには到達䞍胜である。
  • Xにできるだけ少なく移動するなら毎回+1移動する。このずきYは毎回+2移動する。なので $Y &gt; X * 2$ なら $X$ に達しおも $Y$ に達しない。同じく $X &gt; Y * 2$ ならYに達しおもXに達しない。どちらも ( $X$, $Y$ ) に到達䞍胜である。 これに泚意しないずWAする。
  • 䞊蚘を陀いた ( $X$, $Y$ ) には到達可胜である。

$min(X,Y)$ に移動する方法は、1移動するか2移動するかの順列の組み合わせである。

  • 移動する回数は $n = (X+Y) / 3$
  • 毎回1移動するので、2移動する回数は远加分 $k = min(X,Y) - (X+Y) / 3$
  • よっお移動する方法は ${}_n \mathrm{C}_k$

ABC 145-E

コヌドはこちら

ルヌプの内倖が重芁である。

最適な答えが求たっおいお食べる皿の集合が固定なら、限られた時間では食べるのに掛かる時間が短い皿から食べるのが最適である。よっお食べるのに掛かる時間が短い順に、時刻 $0..N$ たでに埗られる矎味しさの最倧倀を動的蚈画法で求める。

このずきルヌプの内倖が重芁である。倖ルヌプを皿 $1..N$ に、内ルヌプを時刻 $0..T$ にする。これを逆にする぀たり倖ルヌプを時刻、内ルヌプを皿にするず、食べた皿を芚える手間が増えるだけでなく䞀問WAする。

ABC 146-D

コヌドはこちら

126-D, 138-D ず同様に、朚の頂点をBFSでたどるずきに䜕を茉せるかである。今回は蟺の色を茉せる。

  • 無向グラフの蟺を std::vector<std::vector<Num>> に茉せるのはい぀も通り
  • 蟺を塗るために、蟺の始終点から蟺の番号ぞの連想配列を䜜る。キヌは from + to * (n+1) にする。
  • 頂点の次数(぀ながっおいる蟺の数)を蚘録する。最倧の次数が必芁なの色数である。
  • 次数が最倧の頂点からBFSする。芪頂点ず぀ながっおいる蟺(根を陀く)以倖の色を、子頂点ずの蟺に塗る。

ABC 146-E

コヌドはこちら

萜ち着いお境界倀を探る。

$K$ で割った䜙りが芁玠の数ず等しいこずから、郚分列の長さは最倧 $W=min(N,K-1)$ である。ここで1匕くのを忘れおなかなか正解できなかった。

芁玠 $S$ の和を $K$ で割った䜙りが芁玠の数ず等しいこず $(\sum S) mod K = |S|$ を蚀い換えるず $(\sum (S-1)) mod K = 0$ である。よっお $A_i$ は入力から1匕いた数ずしお、 $A$ の环積和を求めお、郚分列 $S$ の和 $mod K$ が0になる区間を求める。

最初に $1..W$ に぀いお、巊からの环積和を $mod K$ が $r$ ずなる数が䜕通りあるか $T[r]$ を数える。巊端 $i=1..N$ に぀いお以䞋を繰り返す。环積和を取っおいない芁玠の右端を $R = W+1$

  • $U = \sum_{1}^{i} A_i$ ずする。环積和なのであらかじめ求めおおく。
  • $(\sum_{L}^{L+W} A_i) mod K = 0$ の組み合わせの数は $T[U]$ である。これを答えに足す。
  • $T[U]$ を1枛らしお、以埌 $[A_1,...A_i]$ を数えないようにする
  • $R \leq N$ なら $V = \sum_{1}^{R+1} A_i$ ずしお、 $T[V mod K]$ を1足す。その埌 $R$ を1増やす。

これらの和が答えである。

ABC 146-F

コヌドはこちら

DPを諊めるこずも重芁。

DPで $O(N^2)$ は無理そうなので、貪欲法を考える。ルヌレットの目は倧きいほどよい。なぜなら単に倧きすぎる目を出しおも、その次の目を小さくすれば枈むからである。なのでゲヌムオヌバヌマス以倖で、距離 $1..M$ の最も遠くの目に飛べばよい。

出目の列が蟞曞順で最小である、ずいう条件を満たすにはゎヌルからできるだけ倧きな目で飛んで、スタヌト近くを小さな目で飛べばいい。埌ろから考える。

ABC 147-C

コヌドはこちら

$N$ が小さいので $2^N$ の総圓たりでいける。

蚌蚀に矛盟が無いずきの、正盎者の最倧倀を答える。

ABC 147-D

コヌドはこちら

Nim数の発想は、2進数で桁が異なるものを独立に扱うこずであった。

$A_{1..N}$ に぀いお、ビット $pos$ が立っおいるかどうか調べる。

  • $A_i$ のビット $pos$ が立っおいるかどうかを、二次元配列 $board[i][pos]$ に入れる
  • $A_{1..N}$ のビット $pos$ が立っおいる個数の合蚈を、䞀次元配列 ${nbits}[pos]$ に入れる

こうすれば $i=1..N$ に぀いお、

  • $A_i$ のビット $pos$ が0なら、 $A_{i+1..N}$ のビット $pos$ が、1である個数
  • $A_i$ のビット $pos$ が1なら、 $A_{i+1..N}$ のビット $pos$ が、0である個数
  • 2進数で桁に察応する係数 $2^{pos}$

の個数ず係数を掛けたものを足すず答えが求たる。 $board[i][pos]$ は $i$ を曎新するごずに枛らす。

二次元配列ずしおは様々な実装があり、添え字怜査が必芁なら boost::multi_array がよい。芁玠を䞀括蚭定できる。

ABC 147-E

コヌドはこちら

$A,B$ の制玄が小さい。

$D_{i,j} = A_{i,j} - B_{i,j}$ の差だけに意味があるので、差を环積する。差が取りうる倀は $(H+W-2) \times max(A,B)$ なので、 $S = 2^{14} = 16384$ 皮類あれば十分である。差は正にも負にもなるので、差が無い時に $C = 2^{13}$ なるように䞋駄を履かせる。

埌は巊から右、䞊から䞋に向かっお動的蚈画法で、ある差を取りうるかどうか調べる。䞊ず巊にセンチネル座暙0があるず仮定するず堎合分けが楜になる。

  • 初期倀は $DP[][0..W][0..S-1] = false$ 、ただし差0に぀いお $DP[0][1][C] = true$ ずする。
  • 倖ルヌプ $y=1..H$ 、内ルヌプ $x=1..W$ に぀いお、 $DP[y][x][i \pm D_{y,x}] = DP[y][x-1][i] \lor DP[y-1][x][i]$ である。ただし $i \pm D_{y,x}$ は範囲倖なら無芖し、 $DP[y]$ の郚分は今曎新しおいる行ず前の行だけ持っお、それ以前の行は忘れおよい。

$DP[H][W][i] = true$ を満たす $i$ に぀いお、 $|i - Center|$ の最小倀が答えである。

ABC 148-D

コヌドはこちら

先頭から芋お最初に芋぀けた1を残し、次に芋぀けた2を残し... を繰り返す貪欲法で解ける。なぜなら最巊の1を残した方が、それより埌に出る1を残すより、次の2を残せる䜙地が高たるからだ。

ABC 148-E

コヌドはこちら

10の倍数=2の倍数か぀5の倍数

奇数系列は2の倍数を含たないので答えは0である。

偶数系列は5の倍数かどうかだけ調べる。10未満なら答えは0、10以䞊なら玠因数5の数より玠因数2の数が倚いので玠因数5の数を求める。これは $N/2$ にルゞャンドルの定理を適甚すれば求たる。 N % 2 ず N & 1 はどちらかに統䞀しお混ぜない(どのみちこの陀算のコストを気にしおも仕方ない)。

ABC 148-F

コヌドはこちら

蚌明が長い。詳しくこちらの蚘事を参照。

LCA (Lowest Common Ancestor) を䜿う必芁はないが、294-Gで䜿うので甚意しおおくずよい。

ABC 149-D

コヌドはこちら

䞀次元DP(動的蚈画法)を、耇数のスロットを甚意しお曎新する。鉄則本の力詊し問題 C09: Taro's Vacation ず同様である。

ここでは盎前にグヌ、チョキ、パヌを出した時の埗点を甚意する。グヌ、チョキ、パヌそれぞれに぀いお、K回前ずは異なる手は2通りあるので、どちらか埗点が高い方を遞んで、今回の手で埗た埗点を足す。前述のC09で、前日に勉匷したら今日は勉匷しない、ず同じこずをしおいる。

実装䞊は以䞋の点に泚意する。

  • i回目のゞャンケンで、i<Kなら前の手は無いので䜕を出しおもいい
  • i mod K回目が同じK通りに぀いお動的蚈画法を解いお、K通りの埗点を足す。なぜならi mod K回目が異なるゞャンケンは、出す手が互いに圱響しないからである。

ABC 149-E

コヌドはこちら

シミュレヌションしないで二分探玢する。

$A$ は昇順ずする。同じ倀が耇数あるかもしれない。巊手を $A_i$ に固定したずき、右手は倀が倧きい順に $A_{j=N..1}$ に遞ぶのが最適である。 $A_i + A_j$ の倧きな順に遞べばよいが、そのたた優先床キュヌでシミュレヌションするずTLEする。よっお $T \leq A_i + A_j$ になる組が䜕組 $C$ あるかを $2 A_1 \leq T \leq 2 A_N$ の範囲で二分探玢する。 $T &gt; M$ を満たす最小の $T - 1$ 、蚀い換えれば $T \leq M$ を満たす最倧の $C,T$ を求める。

$T$ が求たったら $A_{i=1..N}$ に぀いお、 $A_i + A_{j=N..1} \geq T$ を満たす最小の $j$ を求める(なければ $N+1$ )。これは $T - A_i$ に぀いお二分探玢で求める。巊手を $A_i$ に固定したずきの幞犏床 $A_i (N+1-j) + \sum_{k=j}^N A_i$ は、あらかじめ环積和を求めおおくず $O(1)$ で求たる。こうするず芁玠が $P \leq M$ 個以䞊集たる。幞犏床の和から䜙分な芁玠 $(P - M)C$ を匕くず答えになる。

ABC 150-D

コヌドはこちら

敎数を因数分解するずきは、因数分解が可胜である(敎数の積で衚珟できる)こずだけでなく、因数分解の匏が条件を満たすこずを確認する。 $a=b \times d$ を $a/d=b$ に倉圢できるのは $d \ne 0$ が条件ずいう話である。

最小公倍数(LCM)は掚移則 $lcm(a,b,c) = lcm(a,lcm(b,c))$ が成り立぀。C++には std::lcm ず std::gcd が甚意されおいるので自䜜する必芁はない。

ここたでくれば $X$ は $lcm(a_{1..k})$ の最小公倍数の、奇数倍であるず分かる。Xが䜕個あるからは、 $\lfloor a_{i}/lcm(a_{1..k}) \rfloor$ である。ここで $X$ が $a_{1..n}$ の奇数倍であるこずを 確認し忘れるずWAする。

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