POJ 3468
線段樹的成段更新加延遲標記
#include<string.h>
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
typedef long long LL;
const int MAXN=111150;
struct Node
{
int l,r;
LL v;
LL c;
}ST[MAXN*3];
void lazysn(int i)//減少了搜索子結點的次數
{
if(ST[i].c)
{
ST[i<<1].c+=ST[i].c;
ST[i<<1|1].c+=ST[i].c;
ST[i<<1].v+=(LL)(ST[i<<1].r-ST[i<<1].l+1)*ST[i].c;
ST[i<<1|1].v+=(LL)(ST[i<<1|1].r-ST[i<<1|1].l+1)*ST[i].c;
ST[i].c=0;
}
}
void Build(int l,int r,int i)
{
ST[i].c=0;
ST[i].l=l;
ST[i].r=r;
int mid=(l+r)>>1;
if(l==r)
{
scanf("%I64d",&ST[i].v);
return ;
}
Build(l,mid,i<<1);
Build(mid+1,r,i<<1|1);
ST[i].v=ST[i<<1].v+ST[i<<1|1].v;
}
void update(int l,int r,int c,int i)
{
int mid=(ST[i].l+ST[i].r)>>1;
if(ST[i].l>=l&&ST[i].r<=r)
{
ST[i].c+=c;
ST[i].v+=(LL)c*(ST[i].r-ST[i].l+1);
return ;
}//如果沒找到符合條件的點,那麼就要遞歸進入子結點
lazysn(i);//所以要結束lazy標記,將子結點的值更新
if(r>mid)
update(l,r,c,i<<1|1);
if(l<=mid)
update(l,r,c,i<<1);
ST[i].v=ST[i<<1].v+ST[i<<1|1].v;
}
/*void prin(int l,int r,int i)
{
printf("[%d,%d]:c:%I64d v:%I64d\n",ST[i].l,ST[i].r,ST[i].c,ST[i].v);
if(l==r)
{
return ;
}
int mid=(l+r)>>1;
prin(l,mid,i<<1);
prin(mid+1,r,i<<1|1);
}*/
LL query(int l,int r,int i)
{
LL ans=0;
int mid=(ST[i].l+ST[i].r)>>1;
if(ST[i].l>=l&&ST[i].r<=r)
{
return ST[i].v;
}
lazysn(i);//同上
if(r>mid)
ans+=query(l,r,i<<1|1);
if(l<=mid)
ans+=query(l,r,i<<1);
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n,m,l,r,c;
scanf("%d%d",&n,&m);
Build(1,n,1);
char s[5];
while(m--)
{
scanf("%s",s);
if(s[0]=='C')
{
scanf("%d%d%d",&l,&r,&c);
update(l,r,c,1);
//prin(1,n,1);
}
else
{
scanf("%d%d",&l,&r);
printf("%I64d\n",query(l,r,1));
}
}
return 0;
}