JOI 2019 予選 E - イルミネーション
木の番号を0,...,N−1として考える。選んだ木のうちいちばん右のものがx−1である場合の美しさの最大値をf(x)とする。xと同時に選べない木 t≤x でもっとも左にあるものをλ(x)とするとき、fの漸化式は
f(x)=Ax−1+t≤λ(x−1)maxf(t)
と書ける。
上の漸化式に従って素朴にDPするとO(n2)になるので、累積和S(x)=max0≤t≤xf(t)で考える:
S(x)=max(f(x),S(x−1))=max(Ax−1+S(λ(x−1)),S(x−1))
求める答えはS(n)なので、Sに関してDPすればよい。
さて、λ(x)をどう求めるかが問題だが、長さNのセグメント木λを作ってλ[x]:=xと初期化し、各区間[L,R]を区間minでLに更新するという方法でテーブルを作った。この場合、計算量はO(N+MlogN)になっている。
解説を見るとO(N+M)でできるらしい。長さNの配列λをやはりλ[x]:=xで初期化し、各クエリ(L,R)をλ[R]:=min(λ[R],L)で処理したあと、後ろからλ[x]:=min(λ[x],λ[x+1])と更新していけばテーブルができている。なるほど……
線型でできそうという感じは確かにしたけど、少し複雑になると累積和的なやり方がぱっと出てこない。