Part 1:前缀和
定义
前缀和是指一个序列前 n 项的和。
用途
例题
输入一个长度为 n 的整数序列。接下来再输入 m 个询问,每个询问输入一对 l,r。对于每个询问,输出原序列中从第 l 个数到第 r 个数的和。
实现
首先做一个预处理,定义一个 sum 数组,表示。对于每次查询,只需回答,时间复杂度。
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
while(q--){
int l,r;
cin>>l>>r;
cout<<sum[r]-sum[l-1]<<endl;
}
Part 2:差分
定义
差分相当于前缀和的逆运算。如果 a 数组的前缀和数组是 sum,那么 a 就是 sum 的差分数组。
for(int i=1;i<=n;i++)
diff[i]=a[i]-a[i-1];
用途
例题
给定区间,要求时间内把加 c。
实现
考虑差分。
由于 a 数组是 b 数组的前缀和数组,所以对 b 数组的的修改,会影响到 a 数组中从及往后的每一个数。
因此我们首先让差分数组 b 中的加 c,a数组变成 。然后我们让减 c,a 数组变成。
这样就在时间内解决这个问题。
for(int i=1;i<=n;i++)
diff[i]=a[i]-a[i-1];
while(q--){
int l,r,c;
cin>>l>>r>>c;
diff[l]+=c;
diff[r+1]-=c;
}