beet's soil

競プロのことなど

ACPC_VC_20191211_DIV1

お ま た せ

~K Perm Counting

包除原理を知っていますか?僕は知っています。
http://compro.tsutajiro.com/archive/181015_incexc.pdf

よく dp[i] := 条件を少なくともi個満たす通り数 みたいにおくと思うんですが(本当か?)、
それなら dp[0] - dp[1] が答えじゃんみたいな気持ちになる

ちゃんと書くと

Sを条件全体の部分集合として way[S] := Sを全て満たすような通り数 とする。
dp[i]=S,|S|=iway[S]
なんですがこれどうやって日本語にすればいいんだろうね 多重和かなあという話になった
(まあ包除的通り数とかで通じそうではある)

この状態から包除原理を適用すると
i=0N(1)idp[i]
で条件を一つも満たさないものの通り数を求めることができる。

この問題においてはまず禁止辺からなるパスの集合に分解して各パスについてDPすればいい

dp[i]=S,|S|=iway[S]=S,|S|=i(Ni)! なので、 cnt[i]=S,|S|=i1 をDPで求めることになる

DPせずに二項係数から出すこともできて、NTTと組み合わせると O(NlogN)になる。

配列外参照で4WAした やめたら?競技プログラミング

Greedy customers

こんなん前から貪欲するしかないやろ! 証明:AC

バチャの意味がないので真面目に証明する

最適解を達成する操作列を適当に持ってくる(操作は有限回なので存在性は明らか)
ある隣接する操作x, yであって、(xの対象) > (yの対象) であるようなものが存在すると仮定する
このとき、操作をswapできる。
(yの対象)<(xの対象) であるので、先にyをしても(yの対象)は変わらないし、
仮定から(xの値)>(yの値)でなければおかしいので、先にyをしても(xの対象) は変わらない。

したがって、swapを繰り返すことで操作列の対象を広義単調増加にすることができる。
つまり、操作列として考えるのは広義単調増加なものだけでよい。

あとはなるべく大きくならないように操作をしていくと上界を達成できそうな気持ちになって、前の方で大きくする理由もないのでOK(雑すぎないか?)

TODO: 書く

AtCoDeerくんと立方体づくり / Building Cubes with AtCoDeer

上と下の面を決めると8点全部決まることに気づけば考察は終わり
実装がたいへーん がんばる 定数倍もやたらきつい

知見としては、回転すると同じになるやつを弾くときに
「setに回転したやつを全部突っ込む」より
「つっこむのは1つにして回転したやつ全てに対してsetの中にあるか見る」
ほうが定数が軽い

適当な全順序をつけて最小のやつを代表元にすると定数が軽い

24倍するとlong longでもオーバーフローするケースが入っており、許せねえ

感想

オーバーフローで全完を逃して、涙が止まらない…