• 前缀和


    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 imes |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)的求法参见最近公共祖先

  • 相关阅读:
    [PHP] Laravel中env函数返回null原因
    [PHP] laravel8 发送通知邮件
    [PHP] hyperf代码热更新-hyperf-watch
    [日常]wps插入页眉页脚
    [linux] du查找数据大的目录
    [PHP] new static()和new self()的区别
    [docker] docker删除容器
    [docker] docker删除镜像
    [javascript] js删除数组中的元素
    [PHP] hyperf框架代码热更新
  • 原文地址:https://www.cnblogs.com/JingFenHuanZhe/p/QianZhuiHe1009.html
Copyright © 2020-2023  润新知