C ガソリンスタンド
@takayuta1999
問題概要 (言い換え)
 N 個の頂点に対して、数 𝑉𝑖 が与えられる
 各頂点対 (𝑖, 𝑗) に対して、𝑖 → 𝑗 に長さ 𝑉𝑗 × |𝑖 − 𝑗| の辺
を張る
 このとき、𝑄個の最短路クエリに答えよ
 1 ≦ 𝑁 ≦ 4000 , 1 ≦ 𝑄 ≦ 200,000
解法
 ワーシャルフロイド法やダイクストラ法ではサイズが大き
すぎるため、時間が間に合わない
 性質をつかもう
解法
 問題文にも明示されてるようにまず一列に頂点を並べて
みる
 終点を固定して生き方を考える
1 2 3 4
解法
 問題文にも明示されてるようにまず一列に頂点を並べて
みる
 終点を固定して生き方を考える
(こういう誤植好き)
1 2 3 4
解法
 終点を固定すると、ありうる道筋としては以下のどちらか
 始点 𝑠 と終点 𝑡 に対して、
𝑠 からどこにも止まらずに直接 𝑡 に行く
𝑠 から別の駅 𝑘 に行ってその後 𝑡 に行く
解法
 終点を固定すると、ありうる道筋としては以下のどちらか
 始点 𝑠 と終点 𝑡 に対して、
𝑠 からどこにも止まらずに直接 𝑡 に行く
𝑠 から別の駅 𝑘 に行ってその後 𝑡 に行く
 上の可能性は別に処理して下だけ考える
解法
 最後に経由する駅 𝑘 が 𝑡 のどちら側に存在するかで場
合分けする
 𝑘 < 𝑡 の時を考える( 𝑡 < 𝑘 の時も同様 )
解法
 𝑘 < 𝑡 の時を考える
 𝑡 より左で初めて 𝑉 の値が𝑉𝑡より大きくなるところを 𝑙 と
する(ない場合は 𝑙 = −1)
解法
 𝑘 < 𝑡 の時を考える
 𝑡 より左で初めて 𝑉 の値が 𝑉𝑡より小さくなるところを 𝑙 と
する(ない場合は 𝑙 = −1)
 このとき、𝑙 = 𝑘 であるとしてよいことを示す
証明
 まず、𝑙 ≦ 𝑘 を示す
 もし、𝑘 < 𝑙 であるとしたら、𝑘 → 𝑡 と行かずに、途中で 𝑙
を経由した方が明らかによい
 よって、𝑙 ≦ 𝑘
証明
 次に、𝑘 ≦ 𝑙 を示す
 もし、𝑙 < 𝑘 であるとしたら、𝑠 ≠ 𝑘 なので、𝑘 の一個前の
位置を場合分けすると、𝑉𝑘 ≧ 𝑉𝑡 だから、𝑘 に行かずにそ
のまま 𝑡 へ行ってもよいと分かり、最短経路として考えな
くてもよいと分かる
 よって、𝑘 ≦ 𝑙
証明
 以上より、𝑘 = 𝑙
 同様に、𝑡 への右からの変移も一意に定めてよい
解法
 以上より、辺が𝑂(𝑁)に減った
 でも、辺の性質上、𝑉 の値が小さい頂点から順にそれを
終点とする最短経路を求めていけば、すべての頂点間
の最短距離が𝑂(𝑁2
)で求められる
 おわり

IJPC-2 C問題解説