您的位置:首页 > 其它

poj3468 A Simple Problem with Integers

2011-08-29 11:04 239 查看
区间求和,区间更新。

需要覆盖区间,延迟处理。

void PushSub(int rt,int m){
if(color[rt]){
color[rt<<1]+=color[rt];
color[rt<<1|1]+= color[rt];
sum[rt<<1]+=color[rt]*(m-(m>>1));
sum[rt<<1|1]+=color[rt]*(m>>1);
color[rt]=0;
}
}


这段刚开始怎么都没搞明白。为什么sum[rt<<1] = c*(m-m>>1) ,而sum[rt<<1|1] = c*(m>>1) 。后来仔细想了一下 ,举个例子[4,8] 这个区间的,二分出来变成[4,6],[7,8]

mid= (4 +8)>>1 = 6 ;左子树的区间是[4,mid].右子树是[mid+1,8],所以这样算起来,如果区间有奇数个,左边肯定要比右边大一个。。。瞬间明白。。。

全部代码:

#include<cstdio>
#define M 100005
#define mid ( l+r )>>1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
__int64 color[M<<2],sum[M<<2];
void PushPlus(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushSub(int rt,int m){ if(color[rt]){ color[rt<<1]+=color[rt]; color[rt<<1|1]+= color[rt]; sum[rt<<1]+=color[rt]*(m-(m>>1)); sum[rt<<1|1]+=color[rt]*(m>>1); color[rt]=0; } }
void Bulid(int l,int r,int rt){
color[l]=0;
if(l == r){
scanf("%I64d",&sum[rt]);
return ;
}
int m= mid;
Bulid(lson);
Bulid(rson);
PushPlus(rt);
}
__int64 Query(int L,int R,int l,int r,int rt){
if(L<=l && r<=R){
return sum[rt];
}
PushSub(rt,r-l+1);
int m=mid;
__int64 ans=0;
if(L<=m)
ans+=Query(L,R,lson);
if(R>m)
ans+=Query(L,R,rson);
return ans;

}
void Change(__int64 x,int L,int R,int l,int r,int rt){

if(L<=l && r<=R){
sum[rt]+=((r-l+1)*x);
color[rt]+=x;
return ;
}
PushSub(rt,r-l+1);
int m = mid;
if(L<=m)
Change(x,L,R,lson);
if(R>m)
Change(x,L,R,rson);
PushPlus(rt);
}
int main(){
int n,m,a,b;
__int64 c;
char op[2];
while(~scanf("%d %d",&n,&m)){
Bulid(1,n,1);
while(m--){
scanf("%s",op);
if(op[0] == 'Q'){
scanf("%d %d",&a,&b);
printf("%I64d\n",Query(a,b,1,n,1));
}
else{
scanf("%d %d %I64d",&a,&b,&c);
Change(c,a,b,1,n,1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: