//线段树成段更新
//和其他题相似,注意在更新时值可以超出int范围,在乘的时候,应乘1ll强制类型转换
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 100005
typedef __int64 i64;
int n,m,t;
i64 sum;
int ans[N];
char str[2];
struct TNode
{
int l,r;
i64 sum,cal;
} node[4*N];
void build(int root,int l,int r)
{
node[root].sum=node[root].cal=0;
node[root].l=l,node[root].r=r;
if(l==r)
{
node[root].sum=ans[l];
return ;
}
int mid=(l+r)>>1,p=root<<1;
build(p,l,mid);
build(p+1,mid+1,r);
node[root].sum=node[p].sum+node[p+1].sum;
}
void insert(int root,int l,int r,int c)
{
int mid,p=root<<1;
if(node[root].l==l&&node[root].r==r)
{
node[root].cal+=c;
node[root].sum+=c*(node[root].r-node[root].l+1);
return ;
}
if(node[root].cal!=0)
{
node[p].cal+=node[root].cal,node[p].sum+=node[root].cal*1ll*(node[p].r-node[p].l+1);
node[p+1].cal+=node[root].cal,node[p+1].sum+=node[root].cal*1ll*(node[p+1].r-node[p+1].l+1);
node[root].cal=0;
}
mid=(node[root].l+node[root].r)>>1;
if(r<=mid) insert(p,l,r,c);
else if(l>mid) insert(p+1,l,r,c);
else
{
insert(p,l,mid,c);
insert(p+1,mid+1,r,c);
}
node[root].sum=node[p].sum+node[p+1].sum;
}
void query(int root,int l,int r)
{
int mid,p;
mid=(node[root].l+node[root].r)>>1;
p=root<<1;
if(node[root].l==l&&node[root].r==r)
{
sum+=node[root].sum;
return ;
}
if(node[root].cal!=0)
{
node[p].cal+=node[root].cal,node[p].sum+=node[root].cal*1ll*(node[p].r-node[p].l+1);
node[p+1].cal+=node[root].cal,node[p+1].sum+=node[root].cal*1ll*(node[p+1].r-node[p+1].l+1);
node[root].cal=0;
}
if(r<=mid) query(p,l,r);
else if(l>mid) query(p+1,l,r);
else
{
query(p,l,mid);
query(p+1,mid+1,r);
}
}
int main()
{
int l,r,c;
scanf("%d%d",&n,&m);
for(l=1; l<=n; l++) scanf("%d",&ans[l]);
build(1,1,n);
while(m--)
{
scanf("%s%d%d",str,&l,&r);
if(l>r) swap(l,r);
if(str[0]=='C')
{
scanf("%d",&c);
insert(1,l,r,c);
}
else
{
sum=0;
query(1,l,r);
printf("%I64d\n",sum);
}
}
return 0;
}
poj3468---线段树
最新推荐文章于 2017-06-19 21:23:05 发布