对操作进行离线。
统计完各个操作次数之后再进行操作。
时间复杂度O(nlog(n)).
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <iostream>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
const int maxn = 200010;
long long lazy[maxn<<2];
long long anstree[maxn];
void opPushDown(int rt)
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
void Add(int l, int r, int rt, int L, int R, long long add)
{
if(L <= l && r <= R)
{
lazy[rt] += add;
return ;
}
opPushDown(rt);
int m = (l + r) >> 1;
if(L <= m) Add(lson, L, R, add);
if(m < R) Add(rson, L, R, add);
}
struct OP
{
int l, r;
long long d;
}op[maxn];
long long Querry(int l, int r, int rt, int L)
{
if(l == r)
return lazy[rt];
opPushDown(rt);
int m = (l + r) >> 1;
if(L <= m)
return Querry(lson, L);
else return Querry(rson, L);
}
int num[maxn];
int main()
{
int n, m, k;
while(cin>>n>>m>>k)
{
for(int i = 1; i <= n; i++)
{
cin>> num[i];
}
for(int i = 1; i <= m; i++)
{
cin >> op[i].l >> op[i].r >> op[i].d;
}
memset(lazy, 0, sizeof(lazy));
for(int i = 0; i < k; i++)
{
int l, r;
cin >> l >> r;
Add(1, m, 1, l, r, 1);
}
for(int i = 1; i <= m; i++)
{
anstree[i] = Querry(1, m, 1, i);
}
for(int i = 1; i <= m; i++)
{
op[i].d *= anstree[i];
}
memset(lazy, 0, sizeof(lazy));
for(int i = 1; i <= n; i++)
{
Add(1, n, 1, i, i, num[i]);
}
for(int i = 1; i <= m; i++)
{
Add(1, n, 1, op[i].l, op[i].r, op[i].d);
}
for(int i = 1; i < n; i++)
{
cout << Querry(1, n, 1, i) << " ";
}
cout << Querry(1, n, 1, n)<< endl;
}
return 0;
}