题目来源:http://poj.org/problem?id=3468
这是线段树的区间更新,用单点更新会超时
#include <iostream> #include <cstdio> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define ll long long const int maxn=100010; ll sum[maxn<<2],lazy[maxn<<2]; void putup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void putdown(int rt,int m){ if(lazy[rt]){ lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; sum[rt<<1]+=lazy[rt]*(m-(m>>1)); sum[rt<<1|1]+=lazy[rt]*(m>>1); lazy[rt]=0; } } void build(int l,int r,int rt){ lazy[rt]=0; if(l==r){ scanf("%lld",&sum[rt]); return; } int m=(l+r)>>1; build(lson); build(rson); putup(rt); } //a,b代表更新的区间[a,b] //value代表区间[a,b]增加的值。 //rt代表当前的根节点 void update(int a,int b,int value,int l,int r,int rt){ //[a,b]和[l,r]没有相交的方; if(a>r||b<l) return ; //[a,b]包含[l,r]的情况 if(a<=l&&b>=r){ lazy[rt]+=value; //注意这儿有个加号 sum[rt]+=(ll)value*(r-l+1); return; } //[a,b]和[l,r]相交的情况 putdown(rt,r-l+1); int m=(l+r)>>1; update(a,b,value,lson); update(a,b,value,rson); putup(rt); } ll query(int a,int b,int l,int r,int rt){ //[a,b]和[l,r]没有相交的情况 if(b<l||a>r) return 0; //把这行代码放在这儿会发生Runtime error //putdown(rt,r-l+1); //[a,b]包含[l,r]的情况 if(a<=l&&b>=r) return sum[rt]; putdown(rt,r-l+1); //[a,b]和[l,r]相交的情况 int m=(l+r)>>1; ll vl=query(a,b,lson); ll vr=query(a,b,rson); return vl+vr; } int main(){ int n,m; int a,b,c; char str[5]; scanf("%d%d",&n,&m); build(1,n,1); while(m--){ scanf("%s",str); if(str[0]=='Q'){ scanf("%d%d",&a,&b); printf("%lld ",query(a,b,1,n,1)); }else if(str[0]=='C'){ scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } } return 0; }