问题描述
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?
(概括:长度为 n 的数组,一共 q 次操作,1 ≤ 𝑛, 𝑞 ≤ 2*10^5。 每次操作给出 L, R , c,表示区间 [L, R] 中各个数均加上 c 。求 q 次操作结束后,数组中各个元素值)
Input
The first line contains two integers n,q(1≤n,q≤2·10^5) — the number of cities and operations.The second line contains elements of the sequence aa: integer numbers a1,a2,…,an(−10 ^ 6 ≤ ai ≤ 10 ^ 6).Then qq lines follow, each line represents an operation. The ii-th line contains three integers l,r and c (1≤l≤r≤n,−10 ^5≤c≤10 ^5) for the ii-th operation.
Output
Print n integers a1,a2,…,an one per line, and aiai should be equal to the final asset value of the ii-th city.
Examples
问题分析
每次操作区间 [L, R] 中各个数均加上 c ,采用枚举的循环处理数组时,需要对R-L+1个数进行加c处理。循环q次,时间复杂度高达O(q*n),很明显会超时,我们需要降低时间复杂度。
采用差分。
• 差分构造方式
• 原数组 A,差分数组 B, 数组范围 [1, n]
• B[1] = B[1]
• B[i] = A[i] - A[i-1]
• 差分特点
• B 数组前缀和 ⇔ A 数组元素值
• SUM{B[1~i]} = A[i] • A 数组的区间加 ⇔ B 数组的单点修改
• A[L]~A[R] 均加上 c • 等价于 B[L] += c, B[R+1] -= c
现在,采用差分,我们将每次区间加操作,降为O(1)。整个程序的时间复杂度O(q)。
参考代码如下:
#include<stdio.h>
long long a[200010];
int main()
{
int n,q,l,r;
long long c;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);//读原数组
//直接在原数组进行差分处理,节省空间
a[0]=0;a[n+1]=0;
for(int i=n;i>0;i--)
a[i]=a[i]-a[i-1];
for(int i=0;i<q;i++)
{
scanf("%d%d%lld",&l,&r,&c);
//区间加操作
a[l]+=c;
a[r+1]-=c;
}
c=a[0];
for(int i=1;i<n;i++)
{
c+=a[i];
printf("%lld ",c);
}
printf("%lld",c+a[n]);
return 0;
}