您的位置:首页 > 其它

kb-07专题--线段树-01-单点修改,区间查和

2015-05-30 22:30 411 查看
给定区间长度,然后给两个操作,单点增加值和单点减值,询问一个区间的人数和;(水)

代码如下:

/*
写的第一个线段树,丑;
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef struct
{
int l,r;
int value;
}tr[100005];//长度是区间长度的四倍;
int n,a[50005]={0},ans=0;
void build(int i,int l,int r)//建树
{
tr[i].l=l;
tr[i].r=r;
if(l==r)
{
tr[i].value=a[l];
return ;
}
build(i*2,l,(l+r)/2);
build(i*2+1,(l+r)/2+1,r);
tr[i].value=tr[i*2].value+tr[i*2+1].value;
}
void ADD(int i,int l,int x)//区间加值
{
if(tr[i].l==l&&tr[i].r==l)
{
tr[i].value+=x;
return ;
}
int t=i<<1;
if(l<=tr[t].r)
ADD(t,l,x);
t+=1;
if(l>=tr[t].l)
ADD(t,l,x);
tr[i].value=tr[i<<1].value+tr[(i<<1)+1].value;
}
void SUB(int i,int l,int x)//区间减值
{
if(tr[i].l==l&&tr[i].r==l)
{
tr[i].value-=x;
return ;
}
int t=i<<1;
if(l<=tr[t].r)
SUB(t,l,x);
t+=1;
if(l>=tr[t].l)
SUB(t,l,x);
tr[i].value=tr[i<<1].value+tr[(i<<1)+1].value;
}
void QUERY(int i,int l,int r)//区间查询寻;
{
if(tr[i].l==l&&tr[i].r==r)
{
ans+=tr[i].value;
return ;
}
i=i<<1;
if(l<=tr[i].r)
{
if(r<=tr[i].r)
QUERY(i,l,r);
else
QUERY(i,l,tr[i].r);
}
i+=1;
if(r>=tr[i].l)
{
if(l>=tr[i].l)
QUERY(i,l,r);
else
QUERY(i,tr[i].l,r);
}
}
int main()
{
int T,t=1;
cin>>T;
while(T--)
{
memset(a,0,sizeof(a));
ans=0;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
printf("Case %d:\n",t++);
build(1,1,n);
char s[10];
int x1,x2;
scanf("%s",s);
int k=0;
while(s[0]!='E')
{
scanf("%d%d",&x1,&x2);
if(s[0]=='A')
ADD(1,x1,x2);
else if(s[0]=='S')
SUB(1,x1,x2);
else if(s[0]=='Q')
{
QUERY(1,x1,x2);
printf("%d\n",ans);
ans=0;
}
scanf("%s",s);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: