您的位置:首页 > 其它

线段树 区域覆盖模版题 pku 3468 A Simple Problem with Integers 线段树——成段操作

2012-08-12 15:06 369 查看
题目连接:http://poj.org/problem?id=3468

题目大意:输入N,和Q,代表n个数字和q个操作,然后输入n个数字,然后再输入q个操作,Q代表求询问a,b编号之间的和(包含),C代表把a,b,之间的数都加上c。

代码:

View Code

#include <stdio.h>
#include <string.h>
#define maxn 100000*4+50
struct node
{
__int64 num;
__int64 lazy;//lazy标记
}tr[maxn];
__int64 count;
void pushup(__int64 rt)
{
tr[rt].num = tr[rt<<1].num+tr[rt<<1|1].num;
}
void build(__int64 l,__int64 r,__int64 rt)
{
if(l == r)//l r基本上就相当于编号~
{
scanf("%I64d",&tr[rt].num);
tr[rt].lazy = 0;//一定让他先为零
return;
}
__int64 m = (l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
return;
}
void pushdown(__int64 rt,__int64 len)
{
if(tr[rt].lazy)
{
tr[rt<<1].lazy += tr[rt].lazy;//一定要是+=哦,因为加法德查询区域为1,3的话,这个lazy标记到1,3就不走了,只有当它再次被询问的时候才往下走。。
tr[rt<<1|1].lazy += tr[rt].lazy;
tr[rt<<1].num += (len-(len>>1))*tr[rt].lazy;
tr[rt<<1|1].num += (len>>1)*tr[rt].lazy;
tr[rt].lazy = 0;
}
return;
}
void update(__int64 lx,__int64 rx,__int64 l,__int64 r,__int64 val,__int64 rt)
{
if(lx <= l && rx >= r)
{
tr[rt].num += val*(r-l+1);
tr[rt].lazy += val;
return;
}
pushdown(rt,r-l+1);
__int64 m = (l+r)>>1;
if(lx <= m)
update(lx,rx,l,m,val,rt<<1);
if(rx > m)
update(lx,rx,m+1,r,val,rt<<1|1);
pushup(rt);
return;
}
__int64 ask(__int64 lx,__int64 rx,__int64 l,__int64 r,__int64 rt)
{
__int64 sum;
sum  = 0;
if(lx <= l && rx >= r)
return tr[rt].num;

pushdown(rt,r-l+1);//询问的时候把lazy往下延伸

__int64 m = (l+r)>>1;
if(lx <= m)//区域不要搞错
sum+=ask(lx,rx,l,m,rt<<1);
if(rx > m)
sum+=ask(lx,rx,m+1,r,rt<<1|1);
return sum;
}
int main()
{
__int64 n,q,i,j,k;
scanf("%I64d %I64d",&n,&q);
char order[5];
build(1,n,1);
while(q--)
{
scanf("%s",order);
if(order[0] == 'Q')
{
__int64 x,y;
scanf("%I64d %I64d",&x,&y);;
printf("%I64d\n",ask(x,y,1,n,1));
}
else
{
__int64 x,y,val;
scanf("%I64d %I64d %I64d",&x,&y,&val);
update(x,y,1,n,val,1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: