题目连接
题意:给你n,m,k;给你n个数,m个形如l,r,d的操作,表示在[l,r]是每一个元素增加d。k个形如x,y,表示执行上面的x到y的操作,问最后数组的样子。
解法:参考qsc,区间的离线处理。用数组t表示每次操作从当前位置到最右边的次数,然后就好办了
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn = 100005;
const int inf = 1<<28;
LL a[maxn];
struct Query{
int L,R;LL d;
}opt[maxn];
LL t[maxn];//t[i]:表示[i,n]操作都做一遍
LL t2[maxn];//同t
int main(){
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=m;i++){
scanf("%d%d%lld",&opt[i].L,&opt[i].R,&opt[i].d);
}
for(int i=1;i<=k;i++){
int x,y;scanf("%d%d",&x,&y);
t[x]++;//[x,n]都加1
t[++y]--;[y+1,n]都减1,刚好就是[x,y]都执行一次
}
LL sum=0;
for(int i=1;i<=m;i++){
sum+=t[i];//累计每个操作的次数
opt[i].d*=sum;
}
for(int i=1;i<=m;i++){
t2[opt[i].L]+=opt[i].d;//累计从当前位置到末尾加的值
t2[opt[i].R+1]-=opt[i].d;
}
sum=0;
for(int i=1;i<=n;i++){
sum+=t2[i];
printf("%lld ",a[i]+sum);
}
return 0;
}