前缀和二维前缀和与差分

Posted emcikem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前缀和二维前缀和与差分相关的知识,希望对你有一定的参考价值。

前缀和

假如给出一串长度为n的数列a1,a2,a3...an,再给出m个询问,每次询问给出L,R两个数,要求给出数列在区间[L,R]的和

普通的方法,时间复杂度为O(n*m)

int a[100005];
for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);

int sum=0;
while(m--)
    for(int i=L;i<=R;i++)
        sum+=a[i];
    

前缀和就是前面i个数的总和,对于每个询问,只需要输出a[R]-a[L-1]即可
用前缀和的方法,时间复杂度O(m+n)

for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);

for(int i=1;i<=n;i++)
    a[i]+=a[i-1];

差分

假如给出一串长度为n的数列a1,a2,a3...an,再给出m次以及不同的L和R[L,R]操作
操作一:将[L,R]内的元素都加上P
操作二:将[L,R]内的元素都减去P
最后求[L,R]内的元素之和

普通方法时间复杂度为O(m*n)

利用差分

#include <bits/stdc++.h>
using namespace std;
const int manx=1e5+5;
int a[maxn],b[maxn];
int main()
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    
    for(int i=1;i<=m;i++)
        int l,r,t,p;//t为操作类型,p为加减的大小
        cin>>t>>l>>r>>p;
        if(t==1)//t==1表示加
            b[l]+=p;b[r+1]-=p;//因为操作一我只需对[L,R]区间里的数加p,[R+1,n]这个区间里的数没必要加p,所以需要减掉p。
        else//t==0表示减
            b[l]-=p;b[r+1]+=p;
        
    
    int add=0;
    for(int i=1;i<=n;i++)
        sum+=b[i];
        a[i]+=a[i-1]+add;
    
    cin>>l>>r;
    printf("%d\n",a[r]-a[l-1]);
    return 0;

以上是关于前缀和二维前缀和与差分的主要内容,如果未能解决你的问题,请参考以下文章

algorithm认真讲解前缀和与差分 (图文搭配)

前缀和与差分

前缀和与差分

前缀和与差分

算法竞赛进阶指南基础算法:前缀和与差分

前缀和差分模板