ARC107

直前までおジャ魔女見てたから「魔法でチョイ2」が脳内に流れていた。前回と同じでよく言えばリラックスして力を発揮できた(まあ正直やる気ない感じ)。

A - Simple Math

2次元バージョンが最近部分問題としてよく出てるので一応瞬殺。本当にそれで正しいか確かめるのはけっこうかかりそう。まあ大きいサンプルもあるし問題の性質からしてそこが合えば大丈夫でしょう。

B - Quadruple

ちょっと怖そうな見た目だけど、とりあえずKを絶対値取っておく(対称性から)。あまり都合よく行く気はしないけどa,bとc,dで分けて掛けるのは?そういえばNが小さくて差が一定なら全列挙できるね。それぞれ何通りあるかは、サイコロ2個の和で大昔から知ってる(競プロ的に言えば典型)。これで解けた。最初、4乗から1乗に落とすの大変そうだと思ったけど、a+b-c-d=kで1つ、足す側と引く側に分けてそれぞれ1つずつ落とせて行けるんだね。答えが3乗程度になってlong longに収まるのは確認していた。

C - Shuffle Permutation

「全てのiについて」の直後に読点が入るような読みもできるじゃん。それだとめっちゃ難しそうな操作になる。複数回swapするかもしれないけど上に「好きな順序で」ってあるし。「好きな回数」が太字な意味もわからなかった。実際は、「全てのiについて」はK以下になる条件のとこにしかかからないんだけど。そういうのもあって、正しい意味がある程度確信できてからもかなり難しい問題というイメージだった。Cが全然わからないのと、Dが好きな見た目をしていたのでまずはDに専念した。

DがTLEして戻ってきた。順位表を見るとCはたくさん解かれている。んーこれ行と列をバラバラに考えれるやつか?たしかに、同じ行の2要素を取って色々なswapをされたときにどう動くかを見てみると同じ行にあるのは変わらない。つまりswapできるところに辺を張って連結成分内なら自由に行き来できる?うーん1と2がswapできて2と3がswapできるからって1と3もできるとは限らんしな。でもその場合も上手いこと別のを経由してできるんじゃ?長いパスを考えると、端同士でもできそう(今考えるとこのときの思考は間違っていた(てきとうすぎた)(ただまあ結論は正しいのだろう)(正直みんな通してるからこれで行けるはずという思い込みが思考をちゃらんぽらんにさせた))。ということで、階乗を掛けていくだけなので事前計算しておく。縦横を2回書かずに済むよう、転置させて2回同じ処理をする。

D - Number of Multisets

解きたくなる見た目。1をちょうど3個使うと決め打ちすると、1/2以下だけをN-3個でK-3を作ることになり、つまり1以下をN-3個で(K-3)*2を作るのと同じだ。DPっぽい。とりあえず書いてみると計算量が3乗になり間に合わないが、まずそれを書いて高速化という方針で行こう。dp[n][k]が答えになるようにする。サンプルが合わなくて気づいたけど更新順序がけっこう特殊だ。dp[i][j]について、iより小さいのは計算済み、残るiが同じケースはj*2のところを参照するのでjは大きい順に計算する必要がある。ここが見慣れないので時間がかかる。DPのタネとしてdp[0][0]=1だけでも足りず、N以下のiに対して全部dp[i][i]=1とする。問題設定通り、jはi以下を維持する(問題設定が違ったとしてもそこは0通りなので関係ない、問題設定が自然なので設定をそのまま使える)。サンプルが現実的な時間で通るのでもう少しいじる。配列の範囲外になるようなところはカットして、最内ループもcontinueからbreakになるよう修正して定数倍高速化。手元でサンプル2が2秒かからないので提出してみた。TLEが23個。やっぱ古いRyzenダメだな。変なところで速い。高速化を考えないといけないので、思考を寝かせるため(あと、最低限もう1問は解きたいので)Cへ。

Cを通して戻ってきたが、DPテーブルはほぼ偶数だけでいいことを思い出す。忘れていた。ここでもdp[n][k]を計算するためにdp[n][k*2]とかが必要なことを忘れる。そこ以外は偶数だけ計算するようにしてけっこう速くなったので提出、TLEが14個。メモ化再帰も選択肢にずっとあったが、定数倍はやや不利だろうしちゃんと考える。最内ループで足すのがdp[8][4],dp[7][2],dp[6][0]などと直線上にあるのは気づいていて、そこの和をどうにかできないかとは思っていたが、DP的に考えると行けそうだ(さっきのはdp[7][2],dp[6][0]の和と計算を共有できるという気づき)。このDPの更新順を守れば、その一つ前の和に現在の値を足すだけで和が求まる。12分くらいあったからどうにか書けた。最後は、どこの和を見ればいいかfor文を使わず計算するややこしさの中で残り5分を切ってきたのでかなりバクバクだった。ACして嬉しかった。TLEは褒められたものじゃないが、3回の提出はどれもムーブとして悪くなかった。