前缀和

update 1009睡觉前,更新了多维前缀和和树上前缀和

前缀和

前缀和

定义

前缀和是一种重要的预处理,能大大降低查询的时间复杂度。

可以简单理解为“数列的前\(n\)项的和”。

实现非常简单。

开两个数组\(A[n],B[n]\)

然后把\(A\)数组前\(n\)项累加放入\(B\)数组。

代码实现:

B[i]=A[i]+B[i-1];

二维/多维前缀和

基于容斥原理

多维前缀和的普通求解方法几乎基于容斥原理(扫雷原理)

比如我们有这样一个矩阵\(\alpha\),可以视为二维数组(借用\(OI~ ~WIKI\)的数据)。

1 2 4 3
5 1 2 4
6 3 5 9

我们同样定义\(sum\)

\[sum_{x,y}=\sum^{x}_{i=1}\sum^{y}_{j=1}a_{i,j} \]

那么所求出的二维前缀和矩阵长成:

1  3  7  10
6  9  15 22
12 18 29 45

为了防止有的人(未来回看的我自己)看不懂上面的\(sum\)式子。

我随便举几个栗子

7=1+2+4

18=1+2+5+1+6+3

这样应该就挺好理解了……吧。

那么显而易见的第一个问题就是通过递推求\(sum\)的过程。

\(sum_{i,j}=sum{i-1,j}+sum_{i,j-1}-sum_{i-1,j-1}+a_{i,j}\)

background Layer 1 1 2 4 3 5 1 2 4 6 3 5 9

如图所示,显然要减去中间重复的一部分。

第二个问题就是如何应用,求\((x1,y1)-(x2,y2)\)子矩阵的和。

那么,根据类似的思考过程,很容易得到答案\(sum_{x2,y2}-sum_{x1-1,y2}-sum_{x2,y1-1}+sum_{x1-1,y1-1}\)

基于\(DP\)思想

基于容斥原理计算的方法优点在于形式简单,不需要特别记忆,但当维数升高时,其复杂度较高。

还有一种通过\(DP\)来计算高维前缀和的方法。

设高维空间\(U\)共有\(N\)维,需要对\(f[\cdot]\)求高维前缀和\(sum[\cdot]\)

\(sum[i][state]\)表示同\(state\)\(D-i\)维相同的所有点对于\(state\)点高维前缀和的贡献。

有定义可知\(sum[0][state]=f[state]\),以及\(sum[state]=sum [D][state]\)

其递推关系为\(sum[i][state]=sum[i-1][state]+sum[i][state']\),其中\(state'\)为第\(i\)维恰好比\(state\)少1的点。

该方法的时间复杂度为\(O(D\times |U|)\),其中\(|U|\)为高维空间\(U\)的大小。

伪代码实现:

for state
	sum[state]=f[state];
for(i=0;i<=D;i++)
	for 以字典序从小到大枚举state
    	sum[state]+=sum[state'];

树上前缀和

\(sum_i\)表示结点\(i\)到根结点的权值总和。

  • 若是边权,\(x\)\(y\)路径上的和为\(sum_x\)+\(sum_y\)-\(2sum_lca\)
  • 若是点权,\(x\)\(y\)路径上的和为\(sum_x\)+\(sum_y\)-\(sum_lac\)-\(sum_{f_{a_{lca}}}\)

\(LCA\)的求法参见最近公共祖先

posted @ 2020-10-09 16:14  Luo_Feng_Han  阅读(96)  评论(0编辑  收藏  举报