文章目录
题目描述
Thanks to everyone’s help last week, TT finally got a cute cat. But what TT didn’t expect is that this is a magic cat.
One day, the magic cat decided to investigate TT’s ability by giving a problem to him. That is select n cities from the world map, and a[i] represents the asset value owned by the i -th city.
Then the magic cat will perform several operations. Each turn is to choose the city in the interval [l,r] and increase their asset value by c. And finally, it is required to give the asset value of each city after q operations.
Could you help TT find the answer?
上星期多亏了大家的帮助,TT终于有了一只可爱的猫。但没想到的是这是一只神奇的猫。
有一天,这只神奇的猫决定给TT一个问题来研究TT的能力。即选择了n个世界地图上的城市,a[i]代表第i个城市拥有的资产价值。 然后魔术猫将执行几个操作。每个回合都要选择区间内的城市[l,r]并将其资产价值增加c。最后,需要给出每个城市在q之后的资产价值。
你能帮TT找到答案吗?
Input
The first line contains two integers n,q(1≤n,q≤2⋅105)— the number of cities and operations.
The second line contains elements of the sequence a
: integer numbers a1,a2,…,a*n*(−106≤ai≤106)
Then q lines follow, each line represents an operation. The i-th line contains three integers l,r and c(1≤l≤r≤n,−105≤c≤105) for the i-th operation.
第一行包含两个整数n,q(1≤n,q≤2⋅105)-城市和业务的数量。第二行包含序列a的元素 :整数a1,a2,…,an(-106≤ai≤106)
接下来是q行,每一行代表一个操作。第i行包含三个整数l,r和c(1≤l≤r≤n,-105≤c≤105),用于第i行操作。
Output
Print n integers a1,a2,…,an one per line, and ai should be equal to the final asset value of the i-th city.
打印n个整数a1,a2,…,*an*每行一个,ai应等于第i个城市的最终资产价值。
Sample Input 1
4 2
-3 6 8 4
4 4 -2
3 3 1
Sample Output 1
-3 6 9 2
Sample Input 2
2 1
5 -2
1 2 4
Sample Output 2
9 2
Sample Input 3
1 2
0
1 1 -8
1 1 -6
Sample Output 3
-14
算法/思路分析
简化题意为:已知一个长度为n的数组a[n],q次操作,每次操作a[l]…a[r]+=c,问q次操作后数组中每个元素的值。
首先,直接按照题意暴力,a数组逐个元素加c,复杂度为O(qn)~O(n^2),而n范围为2e5,会TLE。
考虑优化,注意到每次操作都是区间内的连续元素加同一个值,由此,可以利用差分数组将区间修改转化为单点修改。即构造差分数组b[n-1]:b[1]=a[1],b[i] = a[i] - a[i-1] i ∈[2,n]。则a[l]…a[r] += c 相当于b[l] += c, b[r + 1] -= c。最后,只需求b数组的前缀和即可得a数组的每个元素值a[k] = ∑i=1kb[i]。复杂度为O(n + q)~O(n)
代码
#include <cstdio>
#include <iostream>
#include <stack>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 2e5+10;
#define ll long long
ll n,q,a[maxn],b[maxn];
int main()
{
scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i++) scanf("%lld",&a[i]);
//构建差分数组
b[1] = a[1];
for(int i = 2; i <= n; i++) b[i] = a[i] - a[i-1];
//将a数组的各点增加转化为b数组两个数增加
for(int i = 0; i < q; i++)
{
ll l,r,c;
scanf("%lld%lld%lld",&l,&r,&c);
b[l] += c; b[r+1] -= c;
}
//b数组前缀和即a数组元素值
a[1] = b[1];
for(int i = 2; i <= n; i++) a[i] = a[i-1] + b[i];
for(int i = 1; i <= n; i++)
{
if(i > 1) printf(" ");
printf("%lld",a[i]);
}
printf("\n");
return 0;
}
/*
4 2
-3 6 8 4
4 4 -2
3 3 1
2 1
5 -2
1 2 4
1 2
0
1 1 -8
1 1 -6
*/