题目链接: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);
}
}
}
}