POJ 3468 A simple problem with Integers (线段树区间更新,区间查询) 2/5
题目链接:http://poj.org/problem?id=3468
首先,感谢雨巨的线段树入门视频,可算让我整明白线段树的原理,还学到了一些编码的技巧。orz,再次感谢雨巨。
这道题目就是裸的线段树,区间更新,区间查询
代码:
#include<stdio.h>
#define LL long long
struct SeTreeNode
{
int left,right;
LL int lazy;
LL int len;
LL int sum;
};
SeTreeNode tree[400000];
LL int a[100010];
void build(int id,int l,int r);
void update(int id,int l,int r,LL int val);
void PushDown(int id);
LL query(int id,int l,int r);
int main()
{
int T,n,a1,a2,q;
LL a3;
char s[12];
scanf("%d%d",&n,&q);
for(int i=1 ; i<=n ; i++)
{
scanf("%lld",&a[i]);
}
build(1,1,n);
while(q--)
{
scanf(" %s",s);
scanf("%d%d",&a1,&a2);
if(s[0]=='Q')
{
LL int ans=query(1,a1,a2);
printf("%lld\n",ans);
}
if(s[0]=='C')
{
scanf("%lld",&a3);
update(1,a1,a2,a3);
}
}
return 0;
}
void build(int id,int l,int r)
{
tree[id].left=l,tree[id].right=r;
tree[id].len=tree[id].right-tree[id].left+1;
tree[id].lazy=0;
if(tree[id].left==tree[id].right)
{
tree[id].sum=a[l];
//tree[id].lazy=0;
//tree[id].len=tree[id].right-tree[id].left+1;
return ;
}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
}
LL int query(int id,int l,int r)
{
if(tree[id].left>=l&&tree[id].right<=r)
return tree[id].sum;
if(tree[id].left>r||tree[id].right<l)
return 0;
if(tree[id].lazy)
PushDown(id);
return query(id*2,l,r)+query(id*2+1,l,r);
}
void update(int id,int l,int r,LL int val)
{
if(tree[id].left>=l&&tree[id].right<=r)
{
tree[id].sum+=val*tree[id].len;
tree[id].lazy+=val;
return ;
}
if(tree[id].left>r||tree[id].right<l)
return ;
if(tree[id].lazy)
PushDown(id);
update(id*2+1,l,r,val);
update(id*2,l,r,val);
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
}
void PushDown(int id)
{
if(tree[id].lazy)
{
tree[id*2].lazy+=tree[id].lazy;
tree[id*2+1].lazy+=tree[id].lazy;
tree[id*2].sum+=tree[id].lazy*tree[id*2].len;
tree[id*2+1].sum+=tree[id].lazy*tree[id*2+1].len;
tree[id].lazy=0;
}
}