差分
思想:当我们要在一个数组a[N]的[l,r]区间之中+c的时候,我们可以再创建一个数组b[N],使之a[N]是b[N]的前缀和,b[N]是a[N]的差分,如b[1]=a[1],b[2]=a[2]-a[1]…b[n]=a[n]-a[n-1]。如果我们要在[l,r]加上c,就可以转化为在b[l]+c,b[r+1]-c,这样我们又没改变其a数组,又求出了在这个范围的数加上C的值,然后这个时间复杂度是O(1)的。
注意
他们都是从1开始存储的,因为开始留0是为了对付[l,r]=[1,10]这种情况。当然我们也可以想成原数组a[N]都为0,然后我们插入的a[i]就相当于c,这样也方便我们更好的去构建你所需要的差分数组。
代码。
#include<iostream>
using namespace std;
const int N=100010;
int a[N],b[N];
int n,m;
void insert(int l,int r,int c)
{
b[l]+=c;//高深代码好好理解
b[r+1]-=c;//好代码永远值得去读
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);//输入数据
for(int i=1;i<=n;i++)insert(i,i,a[i]);//构建差分b[i]函数
while(m--)//m次查询
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
insert(l,r,c);//函数也用来在一个数值范围[l,r]加入c
}
for(int i=1;i<=n;i++)b[i]+=b[i-1];//构建前缀和
for(int i=1;i<=n;i++)printf("%d ",b[i]);//输出加入后的值
return 0;
}
结果。
总结。
一个好的程序员是要学会总结的,一定要花时间去重复理解,一定要去好好写几遍。