链接:
http://poj.org/problem?id=3468
题目大意:
有N个整数:A1, A2, ... , AN。 然后对这个整数序列有两种操作:
1. C a b c : 把Aa, Aa+1, ... , Ab所有元素都加上c
2. Q a b : 查询Aa, Aa+1, ... , Ab之和。
分析与总结:
经典线段树题目,线段树的成段更新。
代码:
#include<iostream> #include<cstdio> #include<cstring> #define mem(str,x) memset(str,(x),sizeof(str)) #define len (right-left+1) #define mid ((left+right)>>1) #define lson rt<<1,left,m #define rson rt<<1|1,m+1,right using namespace std; typedef long long int64; const int MAXN = 100005; int64 sum[MAXN<<2], col[MAXN<<2]; inline void push_up(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } inline void push_down(int rt,int _len){ if(col[rt]){ int l = rt<<1, r = rt<<1|1, m = _len>>1; col[l] += col[rt]; col[r] += col[rt]; sum[l] += col[rt] * (_len-m); sum[r] += col[rt] * m; col[rt] = 0; } } void build(int rt,int left,int right){ col[rt] = 0; sum[rt] = 0; if(left==right){ scanf("%lld", &sum[rt]); col[rt] = 0; return; } int m = mid; build(lson); build(rson); push_up(rt); } void update(int rt,int left,int right,int l,int r,int add){ if(l<=left && right<=r){ col[rt] += add; sum[rt] += add*len; return; } push_down(rt,len); int m = mid; if(l <= m) update(lson,l,r,add); if(r > m) update(rson,l,r,add); push_up(rt); } int64 query(int rt,int left,int right,int l,int r){ if(left==l && right==r)return sum[rt]; push_down(rt,len); int m = mid; if(r <= m) return query(lson,l,r); else if(l > m) return query(rson,l,r); else return query(lson,l,m)+query(rson,m+1,r); } int main(){ int n,m,a,b,c; char cmd[3]; while(~scanf("%d%d",&n,&m)){ build(1,1,n); for(int i=0; i<m; ++i){ scanf("%s",cmd); if(cmd[0]=='C'){ scanf("%d%d%d",&a,&b,&c); update(1,1,n,a,b,c); } else{ scanf("%d%d",&a,&b); printf("%lld\n",query(1,1,n,a,b)); } } } return 0; }
—— 生命的意义,在于赋予它意义士。
原创 http://blog.csdn.net/shuangde800 , By D_Double (转载请标明)