前缀与差分
差分的构造:
这样数组A的元素A[i]=sum(B[j])0<j<=i;
如果要对数组A进行区间操作,只要修改两个B数组里面的元素即可。
ps:截图来自课件。
具体题目:
需要实现:长度为n的数组,要进行q个操作;然后就是q个具体操作:区间l–r,加上数字c。输出经过q个操作之后的数组元素。
分析问题
如果直接对数组做q个操作,那么复杂度是O(n*q);复杂度好像有点高,如果用上面的差分数组,那么一个操作就只需要修改2个数据,复杂度是O(2q)。
全部代码:
#include<stdio.h>
using namespace std;
long long int a[3000002],b[3000002];
long long int n,q,l,r,c;
int main()
{
scanf("%lld %lld",&n,&q);
for(long long int i=1;i<=n;i++)
scanf("%lld",&a[i]);
//根据a (n)构建前缀数组b(n-1)
for(long long int i=1;i<=n;i++)
b[i]=a[i]-a[i-1];
//进行操作
for(long long int i=0;i<q;i++)
{
scanf("%lld %lld %lld",&l,&r,&c);
if(l>r)
{
int t=l;l=r;r=t;
}
b[l]=b[l]+c;
b[r+1]=b[r+1]-c;
}
//输出
long long int ans=0;
for(long long int i=1;i<=n;i++)
{
ans=ans+b[i];
printf("%lld ",ans);
}
printf("\n");
return 0;
}