最近开始学习线段树,前天开始的时候看完了百度百科上的线段树介绍,上网搜了许多题目,结果第一次写线段树,居然是二维。。。果断不可做。。。写了四个小时发现思路不对。。。
于是,听说胡浩有一篇线段树的博客很经典,就开始按照博客开始做题了。。。
这是我ac的第一道线段树题目
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define INF 200000000
struct node
{
int u;
int v;
int cover;
int left;
int right;
}tree[100001];
int num[50005],aa,bb,person,tot;
void build(int a,int b)
{
int i,j,k,l,mid;
tot++;
l=tot;
tree[l].u=a;
tree[l].v=b;
tree[l].cover=0;
if(b-a>0)
{
mid=(a+b)/2;
tree[l].left=tot+1;
build(a,mid);
tree[l].right=tot+1;
build(mid+1,b);
}
}
void insert(int a)
{
int mid;
if(aa>=tree[a].u&&aa<=tree[a].v)
tree[a].cover+=bb;;
if(tree[a].v-tree[a].u>0)
{
mid=(tree[a].u+tree[a].v)/2;
if(aa<=mid)
insert(tree[a].left);
else
insert(tree[a].right);
}
}
void delete(int a)
{
int mid;
if(aa>=tree[a].u&&aa<=tree[a].v)
tree[a].cover-=bb;
if(tree[a].v-tree[a].u>0)
{
mid=(tree[a].v+tree[a].u)/2;
if(aa<=mid)
delete(tree[a].left);
else
delete(tree[a].right);
}
}
void search(int a)
{
int mid;
if(tree[a].u>=aa&&tree[a].v<=bb)
person+=tree[a].cover;
else
{
if(tree[a].v-tree[a].u>0)
{
mid=(tree[a].u+tree[a].v)/2;
if(bb<=mid)
search(tree[a].left);
else if(aa>mid)
search(tree[a].right);
else
{
search(tree[a].left);
search(tree[a].right);
}
}
}
}
int main()
{
int n,i,j,k,l,a,b,t;
char s[15];
while(scanf("%d",&t)!=EOF)
{
for(i=1;i<=t;i++)
{
printf("Case %d:\n",i);
scanf("%d",&n);
for(j=1;j<=n;j++)
{
scanf("%d",&num[j]);
}
tot=0;
build(1,n);
for(j=1;j<=n;j++)
{
aa=j;
bb=num[j];
insert(1);
}
while(scanf("%s",&s))
{
if(strcmp(s,"End")==0)
break;
scanf("%d%d",&aa,&bb);
if(s[0]=='A')
{
insert(1);
}
else if(s[0]=='S')
{
delete(1);
}
else if(s[0]='Q')
{
person=0;
search(1);
printf("%d\n",person);
}
}
}
}
return 0;
}