Greg has an array a = a1, a2, ..., an and m operations. Each operation looks as: li, ri, di, (1 ≤ li ≤ ri ≤ n). To apply operation i to the array means to increase all array elements with numbers li, li + 1, ..., ri by value di.
Greg wrote down k queries on a piece of paper. Each query has the following form: xi, yi, (1 ≤ xi ≤ yi ≤ m). That means that one should apply operations with numbers xi, xi + 1, ..., yi to the array.
Now Greg is wondering, what the array a will be after all the queries are executed. Help Greg.
The first line contains integers n, m, k (1 ≤ n, m, k ≤ 105). The second line contains n integers: a1, a2, ..., an (0 ≤ ai ≤ 105) — the initial array.
Next m lines contain operations, the operation number i is written as three integers: li, ri, di, (1 ≤ li ≤ ri ≤ n), (0 ≤ di ≤ 105).
Next k lines contain the queries, the query number i is written as two integers: xi, yi, (1 ≤ xi ≤ yi ≤ m).
The numbers in the lines are separated by single spaces.
On a single line print n integers a1, a2, ..., an — the array after executing all the queries. Separate the printed numbers by spaces.
Please, do not use the %lld specifier to read or write 64-bit integers in C++. It is preferred to use the cin, cout streams of the %I64dspecifier.
3 3 3 1 2 3 1 2 1 1 3 2 2 3 4 1 2 1 3 2 3
9 18 17
1 1 1 1 1 1 1 1 1
2
4 3 6 1 2 3 4 1 2 1 2 3 2 3 4 4 1 2 1 3 2 3 1 2 1 3 2 3
5 18 31 20
题意:长度为n的序列;m种操作:a b c表示第a~b个数的值加上c;k次执行:a b表示执行第a~b种操作。最后输出执行完所有操作后的数列。
先用线段树计算出每种操作执行的次数,将操作中要加的数乘以次数更新。再用线段树求出每个位置的数需要加的最终数值。感觉两个都是简单线段树,就习惯性套模板,而且两个线段树又是先后分开执行,所以写了一个线段树就够了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#define ls node << 1
#define rs node << 1 | 1
#define lson l,mid,ls
#define rson mid + 1,r,rs
#define maxn 100005
using namespace std;
long long a[maxn];
int n,m,k,x,y;
long long cnt[maxn];
struct Operation {
int l;
int r;
long long d;
} o[maxn];
struct Query {
int l;
int r;
long long c;
long long num;
} q[maxn << 2];
void build(int l, int r, int node)
{
q[node].l = l;
q[node].r = r;
q[node].num = 0;
q[node].c = 0;
if(l == r)
return;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
void pushdown(int node,int len)
{
if(q[node].c) {
q[ls].c += q[node].c;
q[rs].c += q[node].c;
q[ls].num += q[node].c * (len - (len >> 1));
q[rs].num += q[node].c * (len >> 1);
q[node].c = 0;
}
}
void update(int x,int y,long long c,int l,int r,int node)
{
if(x <= l && y >= r) {
q[node].c += c;
q[node].num += c * (r - l + 1);
return;
}
pushdown(node, r - l + 1);
int mid = (l + r) >> 1;
if(x <= mid)
update(x,y,c,lson);
if(y > mid)
update(x,y,c,rson);
}
long long findnum(int x, int l, int r, int node)
{
if(x == l && x == r)
return q[node].num;
pushdown(node,r - l + 1);
int mid = (l + r) >> 1;
if(x > mid)
return findnum(x,rson);
if(x <= mid)
return findnum(x,lson);
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k) != EOF) {
for(long long i = 1; i <= n; i++)
scanf("%lld",&a[i]);
for(long long i = 1; i <= m; i++)
scanf("%d%d%lld",&o[i].l,&o[i].r,&o[i].d);
build(1,m,1);
for(long long i = 1; i <= k; i++) {
scanf("%d%d",&x,&y);
update(x,y,1,1,m,1);
}
for(int i = 1; i <= m; i++) {
cnt[i] = findnum(i,1,m,1);
//cout << cnt[i] << endl;
o[i].d *= cnt[i];
}
build(1,n,1);
for(int i = 1; i <= m; i++)
update(o[i].l,o[i].r,o[i].d,1,n,1);
for(int i = 1; i < n; i++)
printf("%lld ",a[i] + findnum(i,1,n,1));
printf("%lld\n",a[n] + findnum(n,1,n,1));
}
}