前缀和和差分专题

前缀和和差分

一维前缀和 一维差分
这些还没整理,后面整理一下 二维前缀和 二维差分 高维前缀和 高维差分 树上前缀和(边权、点权) 树上差分(边权、点权)

1.一维前缀和

原数组为a[]
设sum [i]为\(1~i\)数组\(a\)的和
sum[0]=0;
sum[i]=sum[i-1]+a[i]
\(i\)\(1\)开始
当计算\([l,r]\)的和时,\(O(1)\)答案,为sum[r]-sum[l-1]
如果下标从\(0\)开始,那么询问\(0~r\)时,sum[r]-sum[0-1]会re
所以从\(1\)开始,且sum[0]=0

不是只有加法才有前缀和操作
前缀和操作实质是先正着操作一遍,然后需要时使用操作的逆运算来统计一部分内容
如加法的逆运算是减法
乘法的逆运算是除法
异或的逆运算是它自身
但是乘法不能直接sum[r]/sum[l-1],因为分母不能为0,参见注意事项前缀积
异或有0^a=a a^a=0的性质
可以sum[0]=0
然后sum[i]=sum[i-1]^a[i]
l~r sum[r]^sum[l-1]
sum[r]=a[1]a[2]…a[r]
sum[l-1]=a[1]a[2]…a[l-1]
sum[r]sum[l-1]=00…a[l]a[r]=a[l]…^a[r]

2.二维前缀和

运用容斥原理
设sum[x][y]为[1][1]~[x][y]这一个矩形的和
image
sum[x][y]=sum[x-1][y]+sum[x][y-1]-sum[x-1][y-1]+a[x][y]
要初始化
sum[1][1]==a[1][1]
sum[1][i]=sum[1][i-1]+a[1][i] \(i\)\(2\)开始到\(m\)结束
sum[i][1]=sum[i-1][1]+a[i][1] \(i\)\(2\)开始到\(n\)结束
然后再计算二维前缀和,理论上内外循环\(i\)\(j\)的内外关系随便
\(i\)\(2\)开始 \(j\)\(2\)开始

3.一维差分

差分是前缀和的逆运算
差分用来解决区间加减法问题
且是离线的,假如边修改边查询,就没有意义了
有一个数组\(a\)
现在\(m\)组操作,每组操作把[l,r]内数组元素\(+=c\)
所有操作后输出这个更改后的\(a\)数组
如果每一次操作都暴力\(+=c\),最坏\(O(nm)\),超时
所以可以用差分
一个数组cf【】
先cf[1]=a[1]
cf[i]=a[i]-a[i-1]
i从2~n
这样可以通过对cf数组求前缀和来还原数组
a[1]=cf[1] a[2]=cf[2]+a[1]=a[2]-a[1]+a[1] a[3]=cf[3]+a[2]=a[3]-a[2]+a[2]
那么修改操作呢?
每次只需要cf[l]+=c
cf[r+1]-=c
因为cf[l]+=c
所以对于\(l\)前面的没有影响
对于\(l\)来说,a[l]确实\(+=c\)
对于\(l\)以后的节点来说,因为是前缀和,所以后面的\(a\)都加上了\(c\)
但是当到\(r\)时,a[r]也加上了\(c\)
而到\(r+1\)时,因为cf[r+1]-=c,所以从a[r+1]开始就不再加\(c\)了(加的又减去了)
那么最后还原数组时可以用一个\(sum\)变量,\(sum=0\)
然后\(1~n\),sum+=cf[i] 输出\(sum\)

4.二维差分

5.高维前缀和

6.树上前缀和

7.树上差分

posted @ 2026-01-25 11:33  sakrain  阅读(29)  评论(0)    收藏  举报