前缀和二维前缀和与差分
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;
以上是关于前缀和二维前缀和与差分的主要内容,如果未能解决你的问题,请参考以下文章