Skip to content

Instantly share code, notes, and snippets.

@FF256grhy
Last active September 20, 2019 18:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FF256grhy/46c9d632d7f57f2a10d65989a4c9db1e to your computer and use it in GitHub Desktop.
Save FF256grhy/46c9d632d7f57f2a10d65989a4c9db1e to your computer and use it in GitHub Desktop.
セグメント木コンテストのD問題の解説
yukicoder No. 878 解説
・問題文
No.878 Range High-Element Query - yukicoder
https://yukicoder.me/problems/no/878
・記号
next[i] := min{ k | k > i かつ a[k] > a[i] }
prev[i] := max{ k | k < i かつ a[k] > a[i] }
(ただし a[0] = a[N+1] = ∞ とする)
・解法
普通のセグ木を2つ(sum と arg_max)使う。
まず prev を求める。これは a を後ろから順にスタックに入れながら見て行けば線形時間で可能。
そして b[i] := 1 - #{ j | prev[j] = i } とすると、この b は「任意の i に対し sum b[i, next[i]) = 1」という性質を持つ(証明は後述)。
そのため r' := arg_max a[l, r] とすれば、クエリ [l, r] への答えは sum b[l, r') + 1 となる。
・sum b[i, next[i]) = 1 の証明:
各 i に対し、i から prev[i] への辺を張ったグラフを考えると、b[i] はこのグラフの i の「出次数 - 入次数」である。
次数を [i, next[i]) 全体で考えると、ここへ入る辺はなく、出る辺は i → prev[i] だけなので、sum = 1 となる。(証明終)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment