難易度評価

難易度を1〜10段階で評価できます。投票はあとから変更・取り消しできます。

難易度(投票) 未投票 (0票)

投票の分布

まだ投票はありません。

  1. Lv.10票
  2. Lv.20票
  3. Lv.30票
  4. Lv.40票
  5. Lv.50票
  6. Lv.60票
  7. Lv.70票
  8. Lv.80票
  9. Lv.90票
  10. Lv.100票

難易度の目安を見る ↗

ログインして難易度を投票

外部サイトへ移動します

リンク先の URL を確認してから開いてください。

別タブで開く

Golden Steiner Tree (Hard)

作成者 mackerel38

テスター yukimy32

難易度(作成者設定) Lv.8

難易度(投票) 未投票 (0票)

実行時間制限
2 秒
メモリ制限
512 MiB

解説

グラフの形の考察

Ai=⌊iφ⌋,Bi=⌊iφ2⌋A_i = \left\lfloor i\varphi \right\rfloor, B_i = \left\lfloor i\varphi^2 \right\rfloor とする。

正整数 MM に対して Ai≤MA_i \le M を満たす ii の個数を考える。

i<M+1φi \lt \dfrac{M+1}{\varphi}

なので、これを満たす ii の個数は ⌊M+1φ⌋\left\lfloor \dfrac{M+1}{\varphi} \right\rfloor である。

同様にして、Bi≤MB_i \le M を満たす ii の個数は ⌊M+1φ2⌋\left\lfloor \dfrac{M+1}{\varphi^2} \right\rfloor である。

重複を含めると、このグラフの辺の個数 CMC_M は CM=⌊M+1φ⌋+⌊M+1φ2⌋C_M = \left\lfloor \dfrac{M+1}{\varphi} \right\rfloor + \left\lfloor \dfrac{M+1}{\varphi^2} \right\rfloor

φ2=φ+1\varphi^2 = \varphi + 1 より、M+1φ+M+1φ2=M+1\dfrac{M+1}{\varphi} + \dfrac{M+1}{\varphi^2} = M + 1 であるため、

CM=MC_M = M となる。この等式はすべての正整数 MM に対して成り立つため、

CM+1−CM=1C_{M+1} - C_M = 1 となるため Ai=M,Bi=MA_i = M, B_i = M を満たす正整数 ii がちょうど 11 つであると分かる。

よって、数列 A,BA, B には 1,2,…,M1, 2, \dots, M が 11 つずつ含まれていることが分かる。

自己ループは無視しても答えは変わらないので i=Ai=1i = A_i = 1 のときの赤い辺を無視すれば このグラフは木である と分かる。

また、このグラフを頂点 11 を親とする根付き木としてみると、木の高さは ⌈log⁡φN⌉=O(log⁡N)\left\lceil\log_{\varphi}{N}\right\rceil = O(\log{N}) である。

クエリの処理

このグラフは頂点 11 の自己ループを無視すると木なので、白い頂点をすべて連結にするために残すべき辺は一意に定まり、そのような辺は白い頂点どうしを結ぶパスの和集合である。また、残った辺は部分木をなす。

この部分木に含まれる赤色、青色の辺の個数をそれぞれ CR,CBC_R, C_B とすると求める答えは RCR+BCBRC_R + BC_B である。

頂点 11 を根とし、根から頂点 vv までのパスに含まれる赤色の辺を 0、青色の辺を 1 として、根から順に並べた 01 文字列を SvS_v とする。木の高さは O(log⁡N)O(\log N) なので、SvS_v の長さも O(log⁡N)O(\log N) である。

ここで、f(x)=⌊xφ⌋f(x)=\left\lfloor\dfrac{x}{\varphi}\right\rfloor とすると、頂点 v≥2v\ge 2 の親と、その間の辺の色は以下のように求められる。

  • f(v+1)−f(v)=1f(v+1)-f(v)=1 のとき、親は f(v+1)f(v+1) であり、辺は赤色である。
  • そうでないとき、親は v−f(v+1)v-f(v+1) であり、辺は青色である。

したがって、親を繰り返し求めることで、各頂点の SvS_v を O(log⁡N)O(\log N) で求められる。

頂点を SvS_v の辞書順に並べると、赤色の辺を優先して DFS したときの訪問順と一致する。

白い頂点の個数を kk とする。白い頂点を SvS_v の辞書順に並べたものを v1,v2,…,vkv_1,v_2,\dots,v_k とし、vk+1=v1v_{k+1}=v_1 とする。

頂点 u,vu,v 間のパスに含まれる赤色の辺、青色の辺の個数をそれぞれ dR(u,v),dB(u,v)d_R(u,v),d_B(u,v) とすると

CR=12∑i=1kdR(vi,vi+1), CB=12∑i=1kdB(vi,vi+1)C_R=\dfrac12\displaystyle\sum_{i=1}^k d_R(v_i,v_{i+1}),\ C_B=\dfrac12\displaystyle\sum_{i=1}^k d_B(v_i,v_{i+1}) が成り立つ。

黒色の頂点 vv を白色にするときを考える。頂点を SvS_v の辞書順に並べたとき、vv の直前、直後の白い頂点をそれぞれ s,ts,t とすると

クエリを処理する前では s→ts\to t のパスだったものが、クエリを処理した後では s→v→ts\to v\to t になる。

したがって、赤色と青色両方について C+=12(d(s,v)+d(v,t)−d(s,t))C\mathrel{+}=\dfrac12(d(s,v)+d(v,t)-d(s,t)) と更新すればよい。白色の頂点を黒色にするときはこの逆を行えばよい。

また、Su,SvS_u,S_v の最長共通接頭辞は頂点 u,vu,v の最小共通祖先までのパスを表すため、dR,dBd_R,d_B は文字列の比較によって O(log⁡N)O(\log N) で求められる。

白い頂点の SvS_v をset などで管理すれば、頂点の追加・削除は O(log⁡Qlog⁡N)O(\log Q\log N) で行える。辺の重みを変更するクエリでは CR,CBC_R,C_B は変化しないため、重みだけを更新すればよい。

よって、クエリあたり O(log⁡Qlog⁡N)O(\log Q\log N)、合わせて O(Qlog⁡Qlog⁡N)O(Q\log Q\log N) でこの問題を解くことができた。

ユーザー解説

ユーザー解説を書く

ユーザー解説はまだありません。