您的位置:首页 > 其它

poj 3468 线段树区间更新,模板题

2017-07-25 21:03 417 查看
线段树区间更新模板题,Q是区间查询,求和。C是成段更新。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
__int64 a[100100];
struct node{
__int64 l,r,w,lazy;
}q[4*100100];
void up(int i)
{
q[i].w=q[i*2].w+q[i*2+1].w;
}
void down(__int64 i,__int64 m)
{
if(q[i].lazy)
{
q[i*2].lazy+=q[i].lazy;
q[i*2+1].lazy+=q[i].lazy;
q[i*2].w+=q[i].lazy*(m-(m>>1));
q[i*2+1].w+=q[i].lazy*(m>>1);
q[i].lazy=0;
}
}
void build(__int64 l,__int64 r,__int64 i)
{
q[i].l=l;
q[i].r=r;
q[i].lazy=0;
if(l==r)
{
q[i].w=a[l];
return;
}
int mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
up(i);
}
__int64 query(__int64 l,__int64 r,__int64 i)
{
if(q[i].l==l&&q[i].r==r)
{
return q[i].w;
}
down(i,q[i].r-q[i].l+1);
__int64 sum=0;
int mid=(q[i].l+q[i].r)/2;
if(r<=mid)
sum+=query(l,r,i*2);
else if(l>mid)
sum+=query(l,r,i*2+1);
else
{
sum+=query(l,mid,i*2);
sum+=query(mid+1,r,i*2+1);
}
return sum;
}
void update(__int64 l,__int64 r,__int64 k,__int64 i)
{
if(q[i].l==l&&q[i].r==r)
{
q[i].w=q[i].w+(q[i].r-q[i].l+1)*k;
q[i].lazy+=k;
return;
}
if(q[i].l==q[i].r)
return;
down(i,q[i].r-q[i].l+1);
int mid=(q[i].l+q[i].r)/2;
if(r<=mid)
update(l,r,k,i*2);
else if(l>mid)
update(l,r,k,i*2+1);
else
{
update(l,mid,k,i*2);
update(mid+1,r,k,i*2+1);
}
up(i);
}
int main(void)
{
__int64 i,j,k,n,m,x,y;
char s;
scanf("%I64d%I64d",&n,&m);
for(i=1;i<=n;i++)
scanf("%I64d",&a[i]);
build(1,n,1);
getchar();
for(i=0;i<m;i++)
{
scanf("%c",&s);
if(s=='Q')
{
scanf("%I64d%I64d",&x,&y);
getchar();
k=query(x,y,1);
printf("%I64d\n",k);
}
else if(s=='C')
{
scanf("%I64d%I64d%I64d",&x,&y,&k);
getchar();
update(x,y,k,1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: