差分

差分

例题:

输入一个长度为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


定义s为原数组,b为差分数组;
b[i] = s[i] - s[i - 1]
所以 s为b的前缀和;
证明:
s[n] = s[1] + s[2] + s[2] + … s[n];
s[1] = b[1], s[2] = b[2] - b[1];类推得;
b[i] = b[1] + b[2] - b[1] + b[3] - b[2] + … + b[n] - b[n - 1];
前后抵消,得s为b的前缀和;

因此巧妙方法:
故要在l到r区间增加常数c,只需要在b[l] += c;并且b[r+1] -= c;即可
由前证s为b的前缀和,故这样在b[l]-b[r]值都增加了c,然而在b[r+1]后抵消了;

#include<iostream>
#include<vector>
using namespace std;
vector<int> s(100010,0),b(100010,0);
int main(){
int n,m;
cin>>n>>m;
for(int i = 1; i <= n; i++)cin>>s[i];
for(int i = 1; i <= n; i++)b[i] = s[i] - s[i - 1];
while(m--){
int x,y,z;
cin>>x>>y>>z;
b[x] += z;
b[y + 1] -= z;
}
for(int i = 1; i <= n ;i++){
b[i] += b[i - 1];
cout<<b[i]<<' ';
}
return 0;
}
Author: cheerfulman
Link: http://cheerfulman.github.io/2019/09/17/chafen/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶

Comment