思路:
线段树模拟。
先求操作数,然后操作数 * 增值 再一个线段树就好了
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
struct Seg{
LL Left;
LL Right;
LL sum;
LL flag;
}node1[N<<2], node2[N<<2];
LL a[N];
void PushDown(int num, Seg node[]){
if(node[num].flag){
node[num<<1].flag += node[num].flag;
node[num<<1].sum += node[num].flag * (node[num<<1].Right - node[num<<1].Left + 1);
node[num<<1|1].flag += node[num].flag;
node[num<<1|1].sum += node[num].flag * (node[num<<1|1].Right - node[num<<1|1].Left + 1);
node[num].flag = 0;
}
}
void Build(int num, int Left, int Right, Seg node[]){
node[num].Left = Left;
node[num].Right = Right;
node[num].flag = 0;
if(Left == Right){
node[num].sum = a[Left];
return;
}
int mid = (Left + Right) >> 1;
Build(num<<1, Left, mid, node);
Build(num<<1|1,mid+1,Right,node);
node[num].sum = node[num<<1].sum + node[num<<1|1].sum;
}
void Update(int num, int s, int t, LL val, Seg node[]){
if(node[num].Left >= s && node[num].Right <= t){
node[num].flag += val;
node[num].sum += val * (node[num].Right - node[num].Left + 1LL);
return;
}
PushDown(num, node);
int mid = (node[num].Left + node[num].Right) >> 1;
if(mid >= t) Update(num<<1, s, t, val, node);
else if(mid < s) Update(num<<1|1, s, t, val, node);
else{
Update(num<<1, s, mid, val, node);
Update(num<<1|1, mid + 1, t, val, node);
}
node[num].sum = node[num<<1].sum + node[num<<1|1].sum;
}
LL Query(int num, int v, Seg node[]){
if(node[num].Left == node[num].Right){
if(node[num].Left == v)
return node[num].sum;
return 0;
}
PushDown(num, node);
int mid = (node[num].Left + node[num].Right) >> 1LL;
if(mid >= v) return Query(num<<1, v, node);
return Query(num<<1|1, v, node);
}
int n, m, k;
struct asd{
int Left;
int Right;
LL val;
}q[N];
int u, v;
int main(){
scanf("%d%d%d",&n, &m, &k);
for(int i=1;i<=n;i++) scanf("%I64d", &a[i]);
Build(1, 1, n, node1);
for(int i=1;i<=m;i++)
scanf("%d%d%I64d",&q[i].Left, &q[i].Right, &q[i].val);
for(int i=1;i<=m;i++) a[i] = 0;
Build(1, 1, m, node2);
for(int i=1;i<=k;i++){
scanf("%d%d",&u,&v);
Update(1, u, v, 1LL, node2);
}
for(int i=1;i<=m;i++){
LL op = Query(1,i,node2);
Update(1,q[i].Left,q[i].Right, q[i].val*op, node1);
}
for(int i=1;i<=n;i++)
printf("%I64d ",Query(1,i,node1));
return 0;
}