2021年10月30日土曜日
2021年10月9日土曜日
エクサウィザーズプログラミングコンテスト2021 (ABC 222) G - 222
与えられた数列を(ai)i=0∞ (a0=0,a1=2,a2=22,...)とする。M=[10021],v=[01]とするとき、akはMkvの第一成分に等しい。従って、問題はv=Mkvであるような最小の正整数kを求めることと言い換えられる。
この問題はbaby-step giant-stepで解ける。B=⌈K⌉とする。a0,a1,a2,...,aB−1についてmodKでの値をmapのキー、添字をmapの値として保持しておく。(キーが重複する場合、そこでサイクルに入るので、それまでに0が見つかっていなければ打ち切ってよい。) k=iB−j, j∈{0,1,...,B−1}とする時、v=Mkvが成り立つためにはMjv=MiHvが成り立つ必要がある。したがって、i=1,2,...,BについてMiBvを計算してaiBを求め。この値が先に作ったマップに入っていれば対応する添字jを取り出すとk=iB−jが答えの候補になる。ただし、Mは正則とは限らないので、Mjv=MiBvは必要条件でしかない。つまり、aiB−jmodKが必ず0になるわけではない。実際にMiB−jvを計算して確認する必要がある。
ハッシュテーブルを使った場合の期待計算量はO(K)。
2021年10月3日日曜日
ABC 221 H - Count Multiset
分割数っぽい数え上げなので分割数っぽいDPを考える。
まずは分割数のDPを思い出す。自然数nをk個の正整数の和に分割する場合の数をP(n,k)とする。分割の中に1を含まないものはn−kのk分割のすべての項を1増加させて得られ、分割の中に1を含むものはn−1のk−1分割に1を付加すれば得られるのだった。漸化式で表すと
P(n,k)=P(n−k,k)+P(n−1,k−1)このDPを、同じ数をM個より多くは含まないという制約(以下、単に制約と呼ぶ)に合うように修正することを考える。制約付きの分割の総数をP′(n,k)とする。
上の遷移の一つ目の項、つまり分割の中に1を含まないものをn−kのk分割のすべての項を1増加させて得る場合については、制約はそのまま守られるのでこのままでよさそう。一方、二つ目の項、つまり、分割の中に1を含むものを数えたい場合、このままだと1をM+1個含むものも数えてしまうことになるので、これを除きたい。
nのk分割で1をちょうどM+1個含み、他は制約を満たしているようなものの総数 = n−(M+1)のk−(M+1)分割で1を含まず、かつ制約を満たしているようなものの総数 = n−(M+1)−(k−(M+1))、つまりn−kのk−(M+1)分割で、制約を満たしているようなものの総数
と言い換えると、最後の量はP′(n−k,k−(M+1))に等しいので、漸化式は
P′(n,k)=P′(n−k,k)+P′(n−1,k−1)−P′(n−k,k−(M+1))となる。
スターリング数っぽい数え上げがスターリング数っぽいDPでできる、はけっこう見るけど、分割数っぽい数え上げではうまくいく問題を見た記憶がなくて、遷移を考え始めるまでに時間がかかった……が、例えばJOI 2009 予選 F - ビンゴ がそうだったのを思い出した。
2021年10月2日土曜日
第八回 アルゴリズム実技検定
満点だった。
L - K番目の絶対値
総和の絶対値がD以下であるような連続部分列を数える問題が解ければよさそう。累積和Si=A1+...+Ai上で言い換えると各iについて∣Si−Sj∣≤Dであるようなj<iを数えればよく、これはS0,S1,...,Si−1の中で[Si−D,Si+D]に含まれるようなものを数えることに等しい。数え上げをO(NlogN)で解くと、全体でO(NlogNlog∑i∣Ai∣)。
順序対を数えることにすれば尺取りでできる。確かに。
M - バランス
SoundHound Inc. Programming Contest 2018 Masters Tournament E - + Graph
O - 色分けトーナメント
- トーナメントは2⋅2N−1頂点の完全二分木とすると、制約(Wi,Li)はWiとLiのLCAまでWiとLiが勝ち上がってWiが勝つこととみなせる。
- ある選手を青に塗ると決めても赤に塗ると決めても有効な塗り方は同数ある。(どの有効な塗り方についても、すべての色を反転したものが有効な塗り方であるため。)
dpv[x]=頂点vを根とする部分木に属する左からx番目の選手の色を決め打った時に、部分木vに属する選手の塗り方で(部分木vに含まれる制約を満たし、かつ)vが勝ち上がるようなものの総数、とする。dpvはvの子をc1,c2としてdpc1,dpc2から線形で作れるので、下から処理していけばよい。根に関するdpの総和を2倍したものが答えになる。
各深さのdpの長さの総和はちょうど2Nになるので、全体の計算量はO(N2N+M)。