> makibishi throw|

ABC140E - Second Sum

問題概要

リンク

1,...,N1,...,Nからなる順列PPがある。1L<RN1\leq L < R \leq NとなるL,RL,Rを選んだ時、PL,PL+1,...,PRP_L,P_{L+1},...,P_Rの中で 2 番目に大きいものをXL,RX_{L,R}とする。

この時、L=1N1R=L+1NXL,R\sum_{L=1}^{N-1} \sum_{R=L+1}^{N} X_{L,R}を求めよ。

制約

2N1052 \leq N \leq 10^5

1PiN1 \leq P_i \leq N

PiPj(ij)P_i \neq P_j (i \neq j)

解法

問題が短くわかりやすいので一見簡単そうに見えるが、難しい。

Pi=XL,RP_i=X_{L,R}となる部分列の数

愚直にやるとL,RL,Rの選び方でO(N2)O(N^2)、各部分列のXL,RX_{L,R}を見つけるためにO(N)O(N)なので、全体としてはO(N3)O(N^3)となってしまい間に合わない。

そこで、「ある部分列のXL,RX_{L,R}を求める」のではなく、「各PiP_iについて、Pi=XL,RP_i=X_{L,R}となる部分列の数を数える」ことを考える。

PiP_iの値がXL,RX_{L,R}になっている、つまり 2 番目に大きくなっているような部分列とは、

slice

のようなものや

slice2

のようにPiP_iより大きいものを一つだけ含むような部分列である。

このような部分列の数を考えるために、以下のような、PiP_iよりも大きな値を赤色で表示した図を考える。Pi=XL,RP_i=X_{L,R}となる部分列とは、この図において、PiP_iと「赤色のものを 1 つだけ」含む部分列である。

slice3

そのような部分列の数は、PiP_iのすぐ左側か右側の赤を含んだ部分列をそれぞれ考え、そこから左右にどれだけ伸ばす余地があるかを調べることでカウントすることができる。

上の例で、左側の赤を含んだ最低限の部分列は以下のようになる。

slice3_1

この部分列から、赤を含まないように両端を伸ばすことを考えると、

  • 左には 0,1
  • 右には 0,1,2

だけ伸ばすパターンが考えられ、2×3=62 \times 3=6パターンの部分列が作れる。

右側の赤を含んだ部分列の場合も同様に

slice3_2

  • 左には 0
  • 右には 0

伸ばすパターンがあり、1×1=11 \times 1=1パターンの部分列が作れる。(つまり、これ以上伸ばす余地がない)

左右のパターンの合計は1+6=71 + 6 = 7となる。

Pi=XL,RP_i=X_{L,R}となる部分列の数を求める順番

PiP_iに対して上記のような計算をするためには、PiP_iよりも大きい数の出現位置が分かればよい。 よって、PiP_iの値が大きい順に部分列の数を求めていき、求めおわったPiP_iの出現位置を記録していけば効率的に計算することができる。出現位置の記録を二分ヒープなどで行うことで、PiP_iのすぐ左にある赤そのすぐ左にある赤PiP_iのすぐ右にある赤そのすぐ右にある赤をそれぞれO(logN)O({\rm log} N)で求めることができるため、全体としてもO(NlogN)O( N {\rm log} N)で問題の解が求まる。