poj(3468)セグメントツリーlazy操作
2675 ワード
标题:区間毎の数に1つの数を加えて、1つの区間の和を尋ねる.
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <algorithm>
#define LL long long
#define ls rt<<1
#define rs rt<<1|1
#define lson L,m,rt<<1
#define rson m+1,R,rt<<1|1
#define make_m int m=(L+R)/2;
using namespace std;
const LL N=100005;
struct Node
{
LL L,R;
LL lazy;
LL sum;
}tree[N*4];
LL n,q;
void up(LL rt)
{
tree[rt].sum=(tree[ls].sum+tree[rs].sum);
}
void down(LL rt,LL c)
{
if(tree[rt].lazy)
{
tree[ls].lazy+=tree[rt].lazy;
tree[rs].lazy+=tree[rt].lazy;
tree[ls].sum+=(c-c/2)*tree[rt].lazy;
tree[rs].sum+=(c/2)*tree[rt].lazy;
tree[rt].lazy=0;
}
}
void built(LL L,LL R,LL rt)
{
tree[rt].lazy=0;
tree[rt].L=L;
tree[rt].R=R;
tree[rt].sum=0;
if(L==R)
{
scanf("%lld",&tree[rt].sum);
return ;
}
make_m;
built(lson);
built(rson);
up(rt);
}
void update(LL l,LL r,LL c,LL rt)
{
LL L=tree[rt].L;
LL R=tree[rt].R;
if(L>=l&&R<=r)
{
tree[rt].lazy+=c;
tree[rt].sum+=(LL)c*(R-L+1);
return ;
}
down(rt,R-L+1);
make_m;
if(l<=m)
update(l,r,c,ls);
if(r>m)
update(l,r,c,rs);
up(rt);
}
LL query(LL l,LL r,LL rt)
{
LL L=tree[rt].L;
LL R=tree[rt].R;
if(L>=l&&R<=r)
{
return tree[rt].sum;
}
make_m;
down(rt,R-L+1);
LL ans=0;
if(l<=m)
ans+=query(l,r,ls);
if(r>m)
ans+=query(l,r,rs);
return ans;
}
int main()
{
LL L,R,c;
char ch[20];
scanf("%lld%lld",&n,&q);
built(1,n,1);
while(q--)
{
scanf("%s",ch);
if(ch[0]=='Q')
scanf("%lld%lld",&L,&R), cout<<query(L,R,1)<<endl;
else
scanf("%lld%lld%lld",&L,&R,&c),update(L,R,c,1);
}
return 0;
}