您的位置:首页 > 其它

Codeforces Round #179 (Div. 2) C Greg and Array

2013-04-12 06:50 357 查看
C. Greg and Array

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

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.

Input

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.

Output

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.

Sample test(s)

input
3 3 3
1 2 3
1 2 1
1 3 2
2 3 4
1 2
1 3
2 3


output
9 18 17


input
1 1 1
1
1 1 1
1 1


output
2


input
4 3 6
1 2 3 4
1 2 1
2 3 23 4 4
1 21 3
2 3
1 21 3
2 3


output
5 18 31 20


思路:这个题数据量很大。我用的方法是构造两个线段树来处理

首先要知道线段树的一个比较基本的模型,就是线段树成段的更新(一段+C或-C)

只要知道这个基本模型,题目可以分解为两不,第一步,利用x,y来构造线段树,判断每个操作出现了多少次

然后再把数组a
构造为一颗线段树,并且成段更新的时候,由于第一颗线段树已经可以知道当前这个操作执行了多少次,所以可以直接把di*c作为一个增加的量,来成段更新,这个di就是原来的增量,ci是通过第一颗线段树查找(i,i)这个区间出现的次数

最后把每一个ai都查找一次,就可以得到答案了。

#include<stdio.h>
#include<string.h>

struct node
{
__int64 l;
__int64 r;
__int64 d;
__int64 val;
};
struct control
{
__int64 l;
__int64 r;
__int64 d;
};
node tree1[400000];
node tree2[400000];
control con[100005];
__int64 num[100005],sum1,sum2;
__int64 cnm[100005];

void build_tree1(__int64 l,__int64 r,__int64 root)
{
tree1[root].l=l;
tree1[root].r=r;
if(l==r)
{
tree1[root].val=0;
tree1[root].d=0;
return;
}
__int64 mid=(l+r)>>1;
build_tree1(l,mid,root*2);
build_tree1(mid+1,r,root*2+1);
tree1[root].val=tree1[root*2].val+tree1[root*2+1].val;
tree1[root].d=0;
}

void build_tree2(__int64 l,__int64 r,__int64 root)
{
tree2[root].l=l;
tree2[root].r=r;
if(l==r)
{
tree2[root].val=num[l];
tree2[root].d=0;
return;
}
__int64 mid=(l+r)>>1;
build_tree2(l,mid,root*2);
build_tree2(mid+1,r,root*2+1);
tree2[root].val=tree2[root*2].val+tree2[root*2+1].val;
tree2[root].d=0;
}

void findsum1(__int64 l,__int64 r,__int64 root)
{
if(tree1[root].l==l&&tree1[root].r==r)
{
sum1=sum1+tree1[root].val;
return;
}
sum1=sum1+(r-l+1)*tree1[root].d;
__int64 mid=(tree1[root].l+tree1[root].r)>>1;
if(mid>=r)
findsum1(l,r,root*2);
else if(mid<l)
findsum1(l,r,root*2+1);
else
{
findsum1(l,mid,root*2);
findsum1(mid+1,r,root*2+1);
}
}

void findsum2(__int64 l,__int64 r,__int64 root)
{
if(tree2[root].l==l&&tree2[root].r==r)
{
sum2=sum2+tree2[root].val;
return;
}
sum2=sum2+(r-l+1)*tree2[root].d;
__int64 mid=(tree2[root].l+tree2[root].r)>>1;
if(mid>=r)
findsum2(l,r,root*2);
else if(mid<l)
findsum2(l,r,root*2+1);
else
{
findsum2(l,mid,root*2);
findsum2(mid+1,r,root*2+1);
}
}

void update1(__int64 l,__int64 r,__int64 c,__int64 root)
{
tree1[root].val=tree1[root].val+((r-l+1)*c);
if(tree1[root].l==l&&tree1[root].r==r)
{
tree1[root].d=tree1[root].d+c;
return;
}
__int64 mid=(tree1[root].l+tree1[root].r)>>1;
if(mid>=r)
update1(l,r,c,root*2);
else if(mid<l)
update1(l,r,c,root*2+1);
else
{
update1(l,mid,c,root*2);
update1(mid+1,r,c,root*2+1);
}
}

void update2(__int64 l,__int64 r,__int64 c,__int64 root)
{
tree2[root].val=tree2[root].val+((r-l+1)*c);
if(tree2[root].l==l&&tree2[root].r==r)
{
tree2[root].d=tree2[root].d+c;
return;
}
__int64 mid=(tree2[root].l+tree2[root].r)>>1;
if(mid>=r)
update2(l,r,c,root*2);
else if(mid<l)
update2(l,r,c,root*2+1);
else
{
update2(l,mid,c,root*2);
update2(mid+1,r,c,root*2+1);
}
}

int main()
{
__int64 i,n,a,b,c,m,k;
while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%I64d",&num[i]);
build_tree1(1,m,1);
for(i=1;i<=m;i++)
{
scanf("%I64d%I64d%I64d",&a,&b,&c);
con[i].l=a;
con[i].r=b;
con[i].d=c;
}
for(i=1;i<=k;i++)
{
scanf("%I64d%I64d",&a,&b);
update1(a,b,1,1);
}
for(i=1;i<=m;i++)
{
sum1=0;
findsum1(i,i,1);
cnm[i]=sum1;
}
build_tree2(1,n,1);
for(i=1;i<=m;i++)
update2(con[i].l,con[i].r,con[i].d*cnm[i],1);
for(i=1;i<n;i++)
{
sum2=0;
findsum2(i,i,1);
printf("%I64d ",sum2);
}
sum2=0;
findsum2(n,n,1);
printf("%I64d\n",sum2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: