acwing 差分
题目
输入一个长度为 n 的整数序列。
接下来输入 m 个操作,每个操作包含三个整数 l, r, c,表示将序列中 [l, r] 之间的每个数加上 c。
请你输出进行完所有操作后的序列。
输入格式
第一行包含两个整数 n 和 m。
第二行包含 n 个整数,表示整数序列。
接下来 m 行,每行包含三个整数 l,r,c,表示一个操作。
输出格式
共一行,包含 n 个整数,表示最终序列。
数据范围
1≤n,m≤100000
1≤l≤r≤n
−1000≤c≤1000
−1000≤整数序列中元素的值≤1000
输入样例:
6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1
输出样例:
3 4 5 3 4 2
题解
分析
- 使用循环进行操作时,效率是o(r-l),而使用差分,效率是o(1)
- 差分就是前缀和的逆操作,将差分数组这里叫为b,
b[l]+c
,就可以使l后面所有项的值都增加,然后b[r+1]-c
,将r后面的项还原回去,而题中给的l与r都是从1开始的,所以b[l-1]+c
b[r]-c
- 最后使用一个数组,这里称为c,将差分数组进行前缀和操作,最后输出即可。
代码
#include "iostream"
const int N=100010;
using namespace std;
int num[N]={0};
int b[N]={0};
int d[N]={0};
int main(){
int n1,n2,l,r,c;
cin>>n1>>n2;
for(int i=0;i<n1;i++){
cin>>num[i];
if(i!=0){
b[i]=num[i]-num[i-1];
}
else b[i]=num[i];
}
for(int i=0;i<n2;i++){
cin>>l>>r>>c;
b[l-1]+=c;
b[r]-=c;
}
d[0]=b[0];
for(int i=0;i<n1;i++){
if(i!=0)d[i]+=b[i]+d[i-1];
cout<<d[i]<<' ';
}
}