poj 3468 A Simple Problem with Integers 线段树
线段树的区间加减数,区间查询
#include <cstdio> #include <algorithm> using namespace std; #define LL __int64 const int maxn = 100100; LL sum[4*maxn]; LL add[4*maxn]; void build(int l,int r,int o) { add[o]=0; if(l==r) { scanf("%I64d",&sum[o]); return ; } int m=(l+r)/2; build(l,m,2*o); build(m+1,r,2*o+1); sum[o]=sum[2*o]+sum[2*o+1]; } void update(int ql,int qr,int z,int l,int r,int o) { if(ql<=l&&r<=qr) { add[o]+=z; sum[o]+=(LL)z*(r-l+1); return ; } if(add[o]) { add[2*o]+=add[o]; add[2*o+1]+=add[o]; sum[o*2] += add[o] * (r-l+1 - (r-l+1)/2); sum[o*2+1] += add[o] * ((r-l+1)/2); add[o]=0; } int m=(l+r)/2; if(ql<=m) update(ql,qr,z,l,m,2*o); if(qr>m) update(ql,qr,z,m+1,r,2*o+1); sum[o]=sum[2*o]+sum[2*o+1]; } LL query(int ql,int qr,int l,int r,int o) { if(ql<=l&&r<=qr) return sum[o]; if(add[o]) { add[2*o]+=add[o]; add[2*o+1]+=add[o]; sum[o*2] += add[o] * (r-l+1 - (r-l+1)/2); sum[o*2+1] += add[o] * ((r-l+1)/2); add[o]=0; } LL ans=0; int m=(l+r)/2; if(ql<=m) ans+=query(ql,qr,l,m,2*o); if(qr>m) ans+=query(ql,qr,m+1,r,2*o+1); return ans; } int main() { int n,q; while(scanf("%d%d",&n,&q)!=EOF) { build(1,n,1); char c; int i,j; int x,y,z; getchar(); for(i=1;i<=q;i++) { scanf("%c",&c); if(c=='Q') { scanf("%d%d",&x,&y); printf("%I64d\n",query(x,y,1,n,1)); } else { scanf("%d%d%d",&x,&y,&z); update(x,y,z,1,n,1); } getchar(); } } return 0; }