かんプリンの学習記録

勉強したことについてメモしています. 主に競技プログラミングの問題の解説やってます.

ABC232 G - Modulo Shortest Path

問題はこちら

問題概要

{N}頂点のグラフがあり,頂点{i}から頂点{j}に重み{A_i+B_j\bmod{M}}の有向辺が張られている.頂点{1}から頂点{N}までの最短距離を求めよ.

{2\leq N\leq 2×10^5\\
2\leq M\leq 10^9\\
0\leq A_i,B_i < M}

解説

{A_i+B_j < 2M}であるから{A_i+B_j\bmod{M}}

  • {A_i+B_j < M}なら{A_i+B_j}
  • {A_i+B_j \geq M}なら{A_i+B_j-M}

となります.

頂点を{B}でソートすると,各{i}について{A_i+B_j < M}となる{j}{A_i+B_j \geq M}となる{j}は連続します.したがって,頂点を{B}でソートし(つまり{B_i\leq B_{i+1}}となるように頂点番号を振りなおし)以下のようなグラフを考えればよいです.

  • 頂点は{X_i,Y_i(1\leq i\leq N)}{2N}個.
  • {X_i}から{Y_1}に重み{A_i+B_1}の有向辺を張る({1\leq i\leq N}).
  • {Y_i}から{X_i}に重み{0}の有向辺を張る({1\leq i\leq N}).
  • {Y_i}から{Y_{i+1}}に重み{B_{i+1}-B_i}の有向辺を張る({1\leq i\leq N-1}).
  • {A_i+B_j\geq M}となる最小の{j}に対し,{X_i}から{Y_{j}}に重み{A_i+B_j-M}の有向辺を張る({1\leq i\leq N}).

ソート前の頂点{1,N}がソート後に{s,t}になったとすると,このグラフにおける{X_s}から{X_t}までの最短距離が答えになります.計算量は{O(N\log{N})}です.

後で図とか載せます.(寝るので)

{x_q,y_q,C_q}が与えられるので,頂点{x_q}から{k\in[y_q,N]}に重み{C_q+B_k}の有向辺を張る」といういくつかのクエリを処理した後,頂点{s}から頂点{t}までの最短距離を求めてください.

制約

  • {1\leq x_q,y_q\leq N}
  • {B_i\leq B_{i+1}(1\leq i\leq N-1)}
  • {1\leq s,t\leq N}

この問題が解ければ今回の問題も解けます.
{N=4}の例で説明します.以下のように頂点を増やします.

f:id:kanpurin:20211220174728p:plain:w300

ここで以下のように辺を張ると
f:id:kanpurin:20211220175002p:plain:w300

{x,y,C}のクエリが与えられたときは黒頂点{x}から赤頂点{y}に重み{C+B_y}の有向辺を張ればよいです.答えは黒頂点{s}から黒頂点{t}までの最短距離であり,辺の重みは非負なのでダイクストラ法で解けます.

提出プログラム

https://atcoder.jp/contests/abc232/submissions/28024157

感想

区間に辺を張る問題はよく出ますね.