您的位置:首页 > 其它

poj 3468 A Simple Problem with Integers 线段树

2014-03-11 13:35 309 查看
线段树的区间加减数,区间查询

#include <cstdio>
#include <algorithm>
using namespace std;
#define LL __int64
const int maxn = 100100;
LL sum[4*maxn];
LL add[4*maxn];
void build(int l,int r,int o)
{
add[o]=0;
if(l==r)
{
scanf("%I64d",&sum[o]);
return ;
}
int m=(l+r)/2;
build(l,m,2*o);
build(m+1,r,2*o+1);
sum[o]=sum[2*o]+sum[2*o+1];
}
void update(int ql,int qr,int z,int l,int r,int o)
{
if(ql<=l&&r<=qr)
{
add[o]+=z;
sum[o]+=(LL)z*(r-l+1);
return ;
}
if(add[o])
{
add[2*o]+=add[o];
add[2*o+1]+=add[o];
sum[o*2] += add[o] * (r-l+1 - (r-l+1)/2);
sum[o*2+1] += add[o] * ((r-l+1)/2);
add[o]=0;
}
int m=(l+r)/2;
if(ql<=m) update(ql,qr,z,l,m,2*o);
if(qr>m) update(ql,qr,z,m+1,r,2*o+1);
sum[o]=sum[2*o]+sum[2*o+1];
}

LL query(int ql,int qr,int l,int r,int o)
{
if(ql<=l&&r<=qr)
return sum[o];
if(add[o])
{
add[2*o]+=add[o];
add[2*o+1]+=add[o];
sum[o*2] += add[o] * (r-l+1 - (r-l+1)/2);
sum[o*2+1] += add[o] * ((r-l+1)/2);
add[o]=0;
}
LL ans=0;
int m=(l+r)/2;
if(ql<=m) ans+=query(ql,qr,l,m,2*o);
if(qr>m) ans+=query(ql,qr,m+1,r,2*o+1);
return ans;
}

int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=EOF)
{
build(1,n,1);
char c;
int i,j;
int x,y,z;
getchar();
for(i=1;i<=q;i++)
{
scanf("%c",&c);
if(c=='Q')
{
scanf("%d%d",&x,&y);
printf("%I64d\n",query(x,y,1,n,1));
}
else
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1,n,1);
}
getchar();
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: