F - Fresh tomatoes

2 secs 1024 MB
Ajinoko's icon Ajinoko

キーワード

最小全域木(最大全域木)

解説

NN 個のトマトに対応する NN 個の頂点からなる,辺の無いグラフを考えます。
そして,Ajinoko君の行動に,グラフへの操作を対応させます。

  1. 箱からトマトを 11 つ選び,袋に移す。選んだトマトに対応する頂点を vv とする。
  2. 箱と袋からそれぞれ 11 つずつトマトを選び,1mM1 \leq m \leq M を満たす整数 mm を選ぶ。箱と袋から選んだトマトに対応する頂点の番号をそれぞれ i,ji,j とし,新鮮度をそれぞれ x,yx,y とすると,重みが (x+y)m(modM)(x+y)^m\pmod M の辺 {i,j}\{i,j\} を張る。

すると,全操作終了後のグラフは頂点 vv を根とする全域木となります。

なぜならば,箱に入っているトマトに対応する頂点の集合を SS ,袋に入っているトマトに対応する頂点の集合を TT とすると,行動22の操作を行う度に SS から頂点が 11 つ削除され TT に追加されます。
このとき削除・追加された頂点を ii とすると,ii の親を頂点 jTj \in T とする辺が張られます。行動 22 の操作は S=S= \emptyset となるまで繰り返されるため,全操作終了後には T={1,2,3,...,N}T=\{1,2,3,...,N\} ,かつ,vv を除く TT の任意の要素には親が存在するので,全域木が構成されます。

全操作終了後の元気度は,全域木の重み(各辺の重みの総和)の最大値であるため,求める答えは最大全域木の重みになります。

最大全域木の重みは,プリム法やクラスカル法などによって求めることができます。
グラフの頂点の数を VV ,辺の数を EE とすると,どちらも計算量は O(ElogV)O(E \log V) です。
今回の問題では辺の数は O(N2M)O(N^{2}M) なので,すべての辺を張ろうとすると計算量は O(N2MlogN)O(N^{2}M \log N) となり実行時間制限を超過する場合があります。

そこで少し工夫をします。
ここではプリム法とクラスカル法のどちらも重みが最大の辺から見ていくので,頂点 i,ji,j を端点とする辺を選ぶ際は重みが最大のものを選ぶことになります。
よって,頂点 i,ji,j を端点とする辺は,重みが最大の辺のみを張れば良いです。

2x+y20002 \leq x+y \leq 2000 と範囲が小さいので,2a20002 \leq a \leq 2000 を満たす任意の aa に対し am(modM)a^m \pmod M の最大値を求めておくことで,任意の異なる 22 頂点 i,ji,j に対し辺 {i,j}\{i,j\} の重みの最大値を O(1)O(1) で取り出すことができます。

最終的な計算量は,必要な辺のみを張る部分でO(MmaxA+N2)O(M \max {A} +N^{2}),その後のプリム法またはクラスカル法でO(N2logN)O(N^{2} \log N)なので,全体でO(MmaxA+N2logN)O(M \max A +N^{2} \log N) です。

プリム法による実装例(C++)

類題