初论差分
介绍:
其实最好用的时候是对于一段区间的值就行修改,并且是离线的!
那么用差分就是最好的了,将O(n)的复杂度变成了O(1)的点修改!
讲解
我们假设有5个数字吧!
5 6 12 7 9
那么类似的,我们用前缀的思想来处理相邻的差值!
所以存在了dif[ ] 数组里面!
就有dif[1]=5,dif[2]=1,dif[3]=6,dif[4]=−5,dif[5]=2
那么如果我们将 区间 2~ 4 加上了 98 那么我们的暴力做法就是用一个循环来 保证,
但是我们可以直接将
dif[2]+=98,dif[5]−=98
就变成了: dif[1]=5,dif[2]=99,dif[3]=6,dif[4]=−5,dif[5]=−97
那么最后结尾的时候,只要将前缀来相加就可以了!
a[1]=dif[1]+dif[0] = 5
a[2]=dif[2]+dif[1]=104 —dif[2]=104
a[3]=dif[3]+dif[2]=110 —dif[3]=110
a[4]=dif[4]+dif[3]=105 —dif[4]=105
a[5]=dif[5]+dif[4]=9 —dif[5]=9
代码:
#include <bits/stdc++.h>
#define N 10005
using namespace std;
int n,m,a[N],dif[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
dif[1]=a[1];
for(int i=2; i<=n; i++)
dif[i]=a[i]-a[i-1];
for(int i=1; i<=m; i++)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
dif[l]+=x;
dif[r+1]-=x;
}
for(int i=1; i<=n; i++)
{
dif[i]+=dif[i-1];
printf("%d ",dif[i]);
}
return 0;
}