树状数组

树状数组

树状数组支持的基本操作:单点修改,前缀和查询

一维树状数组

单点修改,区间查询

对于单点修改,直接修改即可。

对于区间查询,拆成 \(sum(r)-sum(l-1)\) 来做。

区间修改,单点查询

考虑在原序列的差分序列上建立树状数组。

于是单点修改转化为前缀和查询。区间修改转化为单点修改 \(tr[l]\gets tr[l]+val\)\(tr[r+1]\gets tr[r+1]-val\)

单点修改,单点查询

只需要将单点修改看做长度为 \(1\) 的区间修改即可。

区间修改,区间查询

最毒瘤的一集,建议用线段树做

我们依然要考虑序列 \(a\) 的差分数组 \(b\)。那么我们可以将区间查询拆成两个前缀和查询,于是只需要考虑查询 \(sum(x)\)

于是

\[\begin{aligned} sum(x)&=\sum_{i=1}^x\sum_{j=1}^i b[j]\\ &=(x+i)\sum_{i=1}^xb[i]-\sum_{i=1}^xi\cdot b[i] \end{aligned} \]

拆成两个树状数组维护,第一个树状数组维护前缀和 \(\sum b[i]\),第二个树状数组维护 \(\sum i\cdot b[i]\)

我们考虑 \(a[i]\gets a[i]+v\)\(\forall i \in [l,r]\)) 后 \(i\cdot b[i]\) 的变化。

\[a_{l-1}, a_l+v, a_{l+1}+v, \cdots, a_{r}+v,a_{r+1} \]

\[\iff b_{l-1},b_l+v,b_{l+1},\cdots,b_r,b_{r+1}-v \]

\[\iff (l-1)b_{l-1},l\cdot b_l\textcolor{cyan}{+l\cdot v},(l+1)\cdot b_{l+1},\cdots, r\cdot b_r, (r+1)\cdot b_{r+1}\textcolor{cyan}{-(r+1)\cdot v} \]

于是我们在维护第二个数组时只需要使 \(l\cdot b[l]\gets l\cdot b[l]+l\cdot v\)\((r+1)\cdot b[r+1] \gets (r+1)\cdot b[r+1]-(r+1)\cdot v\) 即可。

二维树状数组

单点修改,区间查询

对于单点修改,直接修改即可。

对于区间查询,拆成 \(sum(x_2,y_2)-sum(x_1-1,y_2)-sum(x_2,y_1-1)+sum(x_1-1,y_1-1)\) 来做。

区间修改,单点查询

考虑在原序列的差分序列上建立树状数组。

于是单点修改转化为前缀和查询。区间修改转化为单点修改 \(tr[x_1,y_1]\gets tr[x_1,y_1]+val\)\(tr[x_2+1,y_1]\gets tr[x_2+1,y_1]-val\)\(tr[x_1,y_2+1]\gets tr[x_1,y_2+1]-val\)\(tr[x_2+1,y_2+1]\gets tr[x_2+1,y_2+1]+val\)

单点修改,单点查询

只需要将单点修改看做长度为 \(1\) 的区间修改即可。

区间修改,区间查询

最最毒瘤的一集,建议用二维线段树做

我们依然要考虑序列 \(a\) 的差分数组 \(b\)。那么我们可以将区间查询拆成四个前缀和查询,于是只需要考虑查询 \(sum(x,y)\)

于是

\[\begin{aligned} sum(x,y)&=\sum_{i=1}^x\sum_{j=1}^{y}\sum_{k=1}^i\sum_{l=1}^{j} b[k,l]\\ &=\sum_{i=1}^x\sum_{k=1}^i\sum_{j=1}^{y}\sum_{l=1}^{j} b[k,l] \\ &=\sum_{i=1}^x\sum_{k=1}^i\left((y+1)\sum_{j=1}^{y}b[i,j]-\sum_{j=1}^y j\cdot b[i,j] \right) \end{aligned} \]

不妨设 \(c[i]=(y+1)\sum_{j=1}^{y}b[i,j]-\sum_{j=1}^y j\cdot b[i,j]\),继续推导:

\[\begin{aligned} sum(x,y)&=\sum_{i=1}^x\sum_{k=1}^i c[k]\\ &=(x+1)\sum _{i=1}^{x} c[i]-\sum_{i=1}^x i\cdot c[i] \end{aligned} \]

然后还原式子

\[sum(x,y)=(x+1)\sum_{i=1}^x \left((y+1)\sum_{j=1}^{y}b[i,j]-\sum_{j=1}^y j\cdot b[i,j] \right)-\sum _{i=1}^{x} i\cdot \left((y+1)\sum_{j=1}^{y}b[i,j]-\sum_{j=1}^y j\cdot b[i,j] \right) \]

\[=(x+1)(y+1)\sum_{i=1}^x\sum_{j=1}^y b[i,j]-(x+1)\sum_{i=1}^{x}\sum_{j=1}^{y} j\cdot b[i,j]-(y+1)\sum_{i=1}^{x}\sum_{j=1}^{y} i\cdot b[i,j]+\sum_{i=1}^{x}\sum_{j=1}^{y} ij\cdot b[i,j] \]

拆成四个树状数组维护即可。

posted @ 2023-10-25 16:20  Starrykiller  阅读(49)  评论(0)    收藏  举报