エクサウィザーズ2019-D:Modulo Operations
めちゃくちゃ時間をかけてしまったけどこういうのが通せるようになったのは成長かな...。
考察過程・解法
確率に落とすのは苦手なので総和のままやった。
まず最初に,という2つの集合の要素について,で余りをとった値に,で余りをとってもその値は変わらないことに気付こう。したがって,をソートして新たに番号を振り直すことにする。すると,を作ってできた値をとすると,はたちの影響を受けない。このことを用いて,dpを組み立てていこう。
を「黒板にが書かれている状態から始めて,のみを選んで操作をしたときの,最後に黒板に書かれる数字の総和」としよう。こうすると,のについての総和が答えとなる。この理由を説明しよう。を先頭にすると決め打つと,次に書かれる数はとなる。そこからの操作はどうなるかというと,からまでの順番はの部分に表現されているから,残りの個の並べ方だけが自由である。従って,上の式が「を最初に選んだ時の,最後に黒板に書かれる数の総和」を表しており,これをについて足し合わせれば,すべての順列について考えたことになる。
最後にdpの遷移を考えよう。が黒板に書かれているとして,使える数がまでからまでに増えたときに,どのような操作が可能になるだろうか?まず,最初にを選ぶとすると,黒板の数はとなるから,その後の操作によってできる数の総和はもちろんとなる。最初に以下の数を選ぶとすると,その後の操作によってできる数の総和はとなる。がかかっているが,最初に以下の数を選んだので,はどのタイミングで選んでも総和には影響しない。よって,を入れるタイミングの数だけが加算されるということになる。
計算量はであり,C++なら十分間に合う。Pythonだと心配。