标签:nbsp 标记 with return 模板 tle sum 区间更新 name
线段树的模板题吧!区间更新,,,,也可以单点更新,不过会TLE,,,
区间更新的关键在于lazy标记,,,,
如果要更新的区间包括当前的区间的话,就加一个lazy标记,更新整个区间的值,并且停止,
当再次更新到这个区间的时候,就把这个lazy标记pushdown//更新左子树和右子树,同时消除lazy标记,,
# include <cstdio>
# include <iostream>
# include <cstring>
# include <algorithm>
using namespace std;
const int maxn=1e5+5;
long long int sum[maxn*4],seg[maxn*4];
void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
return ;
}
void pushdown(int l,int r,int rt){
int mid=(l+r)>>1;
seg[rt<<1]+=seg[rt];
sum[rt<<1]+=(mid-l+1)*seg[rt];
seg[rt<<1|1]+=seg[rt];
sum[rt<<1|1]+=(r-mid)*seg[rt];
seg[rt]=0;
}
void build(int l,int r,int rt){
seg[rt]=0;
if(l==r) {
scanf("%lld",&sum[rt]);
return ;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
pushup(rt);
}
void update(int L,long long int R,int l,int r,int rt,int c){
if(L<=l&&r<=R) {
seg[rt]+=c;
sum[rt]+=(r-l+1)*c;
return ;
}
if(seg[rt]) pushdown(l,r,rt);
int mid=(l+r)>>1;
if(L<=mid) update(L,R,l,mid,rt<<1,c);
if(mid<R) update(L,R,mid+1,r,rt<<1|1,c);
pushup(rt);
}
long long int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
if(seg[rt]) pushdown(l,r,rt);
int mid=(l+r)>>1;
long long int ans=0;
if(L<=mid) ans+=query(L,R,l,mid,rt<<1);
if(mid<R) ans+=query(L,R,mid+1,r,rt<<1|1);
pushup(rt);
return ans;
}
int main(){
long long int n,q;
while(scanf("%lld%lld",&n,&q)==2&&n&&q){
build(1,n,1);
char s[5];
long long int a,b;
int c;
for(long long int i=0;i<q;i++){
scanf("%s",s);
if(s[0]==‘Q‘){
scanf("%lld%lld",&a,&b);
printf("%lld\n",query(a,b,1,n,1));
}
if(s[0]==‘C‘){
scanf("%lld%lld%d",&a,&b,&c);
update(a,b,1,n,1,c);
}
}
}
return 0;
}
POJ-3468 A Simple Problem with Integers
标签:nbsp 标记 with return 模板 tle sum 区间更新 name
原文地址:http://www.cnblogs.com/lintanxi/p/6786506.html