http://poj.org/problem?id=3468
整段更新,整段查询
PushUp(int rt) 是把当前结点的信息更新到父结点
PushDown(int rt) 是把当前结点的信息更新到儿子结点
延迟标记:
简单来说就是每次更新的时候不要更新到底,用延迟标记
使得更新延迟到下次需要更新or询问到的时候
/*
* 整段更新,整段查询
* PushUp(int rt) 是把当前结点的信息更新到父结点
* PushDown(int rt) 是把当前结点的信息更新到儿子结点
* 延迟标记:
* 简单来说就是每次更新的时候不要更新到底,用延迟标记
* 使得更新延迟到下次需要更新or询问到的时候
* */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define N 111111
struct node
{
int l, r;
LL add, sum;
}tree[N*4];
int num[N];
void PushUp(int rt)
{
tree[rt].sum = tree[LL(rt)].sum + tree[RR(rt)].sum;
}
void PushDown(int rt, int len)
{
if(tree[rt].add)
{
tree[LL(rt)].add += tree[rt].add;
tree[RR(rt)].add += tree[rt].add;
tree[LL(rt)].sum += tree[rt].add*(len-(len>>1));
tree[RR(rt)].sum += tree[rt].add*(len>>1);
tree[rt].add = 0;
}
}
void build(int rt, int l, int r)
{
tree[rt].l = l, tree[rt].r = r, tree[rt].add = 0;
if(l == r)
{
tree[rt].sum = num[l];
return ;
}
int mid = (l + r) >> 1;
build(LL(rt), l, mid);
build(RR(rt), mid+1, r);
PushUp(rt);
}
void update(int rt, int l, int r, int val)
{
if( l <= tree[rt].l && tree[rt].r <= r)
{
tree[rt].add += val;
tree[rt].sum += val*(tree[rt].r - tree[rt].l + 1);
return ;
}
PushDown(rt, tree[rt].r - tree[rt].l + 1);
int mid = ( tree[rt].l + tree[rt].r) >> 1;
if( l <= mid) update(LL(rt), l, r, val);
if( r > mid) update(RR(rt), l, r, val);
PushUp(rt);
}
LL query(int rt, int l, int r)
{
if( l <= tree[rt].l && tree[rt].r <= r)
{
return tree[rt].sum;
}
PushDown(rt, tree[rt].r - tree[rt].l + 1);
int mid = ( tree[rt].l + tree[rt].r) >> 1;
LL ret = 0;
if( l <= mid) ret += query(LL(rt), l, r);
if( r > mid) ret += query(RR(rt), l, r);
return ret;
}
int main()
{
int n, q, i;
scanf("%d%d",&n,&q);
for(i=1; i<=n; ++i)
scanf("%d",&num[i]);
build(1,1,n);
// for(i=1; i<=n; ++i)
// {
// printf("%d %d:%lld\n",tree[i].l, tree[i].r, tree[i].sum);
// }
while(q--)
{
char cmd[10];
int a, b, c;
scanf("%s",cmd);
if(cmd[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%I64d\n",query(1,a,b));
}else
{
scanf("%d%d%d",&a,&b,&c);
update(1,a,b,c);
}
}
return 0;
}