单点修改单点查询的线段树模板题
也可以树状数组做,这里不详细介绍。。
我的线段树做法见代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 50000
int n;
int num[MAXN+1];
typedef struct AAA
{
int l, r;
struct AAA *lchild,*rchild;
int date;
}NODE;
NODE *build(int a,int b) //建树
{
NODE *u=(NODE *)malloc(sizeof(NODE));
if(a==b)
{
u->rchild=u->lchild=NULL;
u->l=u->r=a;
u->date=num[a];
return u;
}
u->r=b;
u->l=a;
int m=(a+b)>>1;
u->lchild=build(a,m);
u->rchild=build(m+1,b);
u->date=u->lchild->date+u->rchild->date;
return u;
}
int qy(int a,int b,NODE *u) //右孩子查询
{
if(a==b)
return num[a];
int m=(u->l+u->r)>>1;
if(b>m)
{
return u->lchild->date+qy(m+1,b,u->rchild);
}
return qy(a,b,u->lchild);
}
int qz(int a,int b,NODE *u) //左孩子查询
{
if(a==b)
return num[a];
int m=(u->l+u->r)>>1;
if(a<=m)
{
return u->rchild->date+qz(a,m,u->lchild);
}
return qz(a,b,u->rchild);
}
void qq(int a,int b,NODE *u) //查询
{
if(a==b)
{
printf("%d\n",num[a]);
return;
}
int m=(u->l+u->r)>>1;
if(a>m)
{
qq(a,b,u->rchild);
}
else if(b<=m)
{
qq(a,b,u->lchild);
}
else{
printf("%d\n",qz(a,m,u->lchild)+qy(m+1,b,u->rchild));
return;
}
}
void insert(int a,int b,NODE *u) //修改
{
u->date+=b;
if(u->r==u->l)
{
num[a]+=b;
return;
}
int m=(u->l+u->r)>>1;
if(a>m)
insert(a,b,u->rchild);
else
insert(a,b,u->lchild);
}
int main()
{
NODE *root;
char str[10];
int t,i,j=0;
scanf("%d",&t);
int a,b;
while(t--)
{
printf("Case %d:\n",++j);
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
root=build(1,n);
while(1)
{
scanf("%s",str);
if(!strcmp(str,"Query"))
{
scanf("%d%d",&a,&b);
qq(a,b,root);
}
else if(!strcmp(str,"Sub"))
{
scanf("%d%d",&a,&b);
insert(a,-b,root);
}
else if(!strcmp(str,"Add"))
{
scanf("%d%d",&a,&b);
insert(a,b,root);
}
else
break;
}
}
return 0;
}