题目链接:http://poj.org/problem?id=3468
题意:给出n个数,2种操作,一种将[l,r]中得数同时加上val,一种是查询[l,r]所有数之和
思路:又是区间更新和查询(树状数组就可以很好的解决),也是典型的线段树,lazy标志用法和之前有些不一样,每次更新成新区间的和与旧区间和的差值,查询时要把lazy标志向子节点推(这一步另外写一个函数会好看很多,lazy更新时犯了点小错查了很久,被angod狠狠的嘲笑了)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 100030 #define LL long long using namespace std; struct Tree { int l,r; LL date; }tree[maxn*3]; int s[maxn]; LL lazy[maxn*3]; void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; if (l==r) { tree[root].date=s[l]; return; } int mid=(l+r)>>1; build (root<<1,l,mid); build (root<<1|1,mid+1,r); tree[root].date=tree[root<<1].date+tree[root<<1|1].date; } void update(int root,int l,int r,int val) { if (tree[root].l>=l && tree[root].r<=r) { tree[root].date+=(LL)val*(tree[root].r-tree[root].l+1); lazy[root]+=val; return; } if (lazy[root]!=0) { lazy[root<<1]+=lazy[root]; lazy[root<<1|1]+=lazy[root]; tree[root<<1].date+=lazy[root]*(tree[root<<1].r-tree[root<<1].l+1); tree[root<<1|1].date+=lazy[root]*(tree[root<<1|1].r-tree[root<<1|1].l+1); lazy[root]=0; } int mid=(tree[root].l+tree[root].r)>>1; if (l<=mid) update(root<<1,l,r,val); if (r>mid) update(root<<1|1,l,r,val); tree[root].date=tree[root<<1].date+tree[root<<1|1].date; } long long que(int root,int l,int r) { if (tree[root].l==l && tree[root].r==r) { return tree[root].date; } if (lazy[root]!=0) { lazy[root<<1]+=lazy[root]; lazy[root<<1|1]+=lazy[root]; tree[root<<1].date+=lazy[root]*(tree[root<<1].r-tree[root<<1].l+1); tree[root<<1|1].date+=lazy[root]*(tree[root<<1|1].r-tree[root<<1|1].l+1); lazy[root]=0; } int mid=(tree[root].l+tree[root].r)>>1; if (r<=mid) return que(root<<1,l,r); else if (l>mid) return que(root<<1|1,l,r); else return que(root<<1,l,mid)+que(root<<1|1,mid+1,r); } int main() { int n,m; while (scanf("%d%d",&n,&m)!=EOF) { memset(lazy,0,sizeof(lazy)); for (int i=1;i<=n;i++) { scanf("%d",&s[i]); } build(1,1,n); for (int i=0;i<m;i++) { char op; cin>>op; if (op=='Q') { int a,b; scanf("%d%d",&a,&b); printf("%I64d\n",que(1,a,b)); } else { int a,b,p; scanf("%d%d%d",&a,&b,&p); update(1,a,b,p); } } } }