1. 程式人生 > 其它 >洛谷P4458 [BJOI2018]鏈上二次求和

洛谷P4458 [BJOI2018]鏈上二次求和

洛谷P4458 [BJOI2018]鏈上二次求和

有一條長度為 \(n\) 的鏈(連線方式為 \(1-2-3-\cdots-n\)),第 \(i\) 個點的權值為 \(a_i\)
\(m\) 個操作,分為修改和查詢兩類:

  1. 修改:將 \(u\)\(v\) 路徑上所有點的權值加上 \(d\)
  2. 查詢:對於所有包含 \(l\sim r\) 個點的路徑計算上面的點的權值之和,再求總和,對 \(10^9+7\) 取模。

\(n\le 2\times10^5,m\le 5\times10^5\)
\(1\le u\le n,1\le v\le n,l\le r\le n\)

對於修改操作,差分一下即可 \(O(1)\)

解決。
難點在於如何處理查詢。
\(a\) 的字首和為 \(s\)\(s\) 的字首和為 \(S\)

\[\begin{aligned} ans&=\sum_{i=l}^r\sum_{j=0}^{n-i}s_{j+i}-s_j \\ &=\sum_{i=l}^rS_n-S_{i-1}-S_{n-i}\\ &=(r-l+1)S_n-\sum_{i=l-1}^{r-1}S_i-\sum_{i=n-r}^{n-l}S_i \end{aligned}\]

需要對 \(S\) 進行區間求和,因此再做一次字首和。
\({SS}_x=\sum\limits_{i=1}^xS_i\)

,則

\[ans=(r-l+1)({SS}_n-{SS}_{n-1})-{SS}_{r-1}+{SS}_{l-2}-{SS}_{n-l}+{SS}_{n-r-1} \]

現在的問題是如何求出 \({SS}_x\),或者說如何用差分陣列 \(d_x=a_x-a_{x-1}\) 表示 \({SS}_x\)

\(SS\) 實際上是由 \(d\) 求 4 次字首和得到的,所以

\[{SS}_x=\sum_{i=1}^x\sum_{j=1}^i\sum_{k=1}^j\sum_{t=1}^kd_t \]

變換求和順序

\[{SS}_x=\sum_{t=1}^xd_t\sum_{i,j,k}[t\le k\le j\le i\le x] \]

後面的求和式可以爆算一下,等於 \(\dfrac{(x+1-t)(x+2-t)(x+3-t)}6\)

或者用組合計數的方法處理:
\(t\le k\le j\le i\le x\) 等價於 \(t\le k<j+1<i+2\le x+2\)
求符合條件的 \(i,j,k\) 的組數,其實就是從 \(t\sim x+2\) 中選 3 個不同的整數,方案數為 \(C_{x-t+3}^3\)

將結果代回原式,得到

\[6SS_x=\sum_{i=1}^x(x+1-i)(x+2-i)(x+3-i)d_i \]

大力展開

\[6SS_x=(x+1)(x+2)(x+3)\mathbf{\sum_{i=1}^xd_i}-(3x^2+12x+11)\mathbf{\sum_{i=1}^xid_i} +(3x+6)\mathbf{\sum_{i=1}^xi^2d_i}-\mathbf{\sum_{i=1}^xi^3d_i}\]

用樹狀陣列維護加粗的 4 個式子即可。

時間複雜度為 \(O(nk+mk\log n)\),這裡 \(k=4\)