#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int N=4050;
int Max;
struct cnode
{
int cl,cr;
int sum;
};
struct node
{
int l,r;
cnode ctree[N];
}tree[N];
int max(int a,int b)
{
return a>b?a:b;
}
void cbuild(int root,int croot,int cl,int cr)//建立子树
{
tree[root].ctree[croot].cl=cl;
tree[root].ctree[croot].cr=cr;
tree[root].ctree[croot].anum=0;
tree[root].ctree[croot].bnum=0;
//printf("%d %d\n",tree[root].ctree[croot].cl,tree[root].ctree[croot].cr);
if(cl==cr)
{
if(cl%2==0)
tree[root].ctree[croot].bnum=1;
else
tree[root].ctree[croot].anum=1;
}
int cmid=(cl+cr)>>1;
cbuild(root,croot<<1,cl,cmid);
cbuild(root,croot<<1|1,cmid+1,cr);
tree[root].ctree[croot].anum+=tree[root].ctree[croot<<1].anum+tree[root].ctree[croot<<1|1].anum;
tree[root].ctree[croot].bnum+=tree[root].ctree[croot<<1].bnum+tree[root].ctree[croot<<1|1].bnum;
}
void build(int root,int l,int r,int cl,int cr)//建立母树
{
tree[root].l=l;
tree[root].r=r;
cbuild(root,1,cl,cr);
if(l==r)
{
return ;
}
int mid=(r+l)>>1;
build(root<<1,l,mid,cl,cr);
build(root<<1|1,mid+1,r,cl,cr);
}
void cupdata(int step,int s,int a,int sum)//更新到子树的线段
{
if(tree[step].ctree[s].cl==tree[step].ctree[s].cr)
{
tree[step].ctree[s].sum=max(tree[step].ctree[s].sum,sum);
return ;
}
int cmid=(tree[step].ctree[s].cl+tree[step].ctree[s].cr)>>1;
if(a<=cmid)
{
cupdata(step,s<<1,a,sum);
}
else
{
cupdata(step,s<<1|1,a,sum);
}
tree[step].ctree[s].sum=max(tree[step].ctree[s].sum,sum);
}
void updata(int step,int h,int a,int sum)//更新母树线段
{
cupdata(step,1,a,sum);//首先要先更新到子树中去
if(tree[step].l==tree[step].r)
{
return ;
}
int mid=(tree[step].r+tree[step].l)>>1;
if(h<=mid)
{
updata(step<<1,h,a,sum);
}
else
{
updata(step<<1|1,h,a,sum);
}
}
void subcompute(int step,int s,int a1,int a2)//在子树中统计
{
if(tree[step].ctree[s].cl==a1&&tree[step].ctree[s].cr==a2)
{
if(Max<tree[step].ctree[s].sum)
{
Max=tree[step].ctree[s].sum;
}
return ;
}
int cmid=(tree[step].ctree[s].cl+tree[step].ctree[s].cr)>>1;
if(a2<=cmid)
{
subcompute(step,s<<1,a1,a2);
}
else
{
if(a1>cmid)
{
subcompute(step,s<<1|1,a1,a2);
}
else
{
subcompute(step,s<<1,a1,cmid);
subcompute(step,s<<1|1,cmid+1,a2);
}
}
}
void compute(int step,int h1,int h2,int a1,int a2)
{
if(tree[step].l==h1&&h2==tree[step].r)
{
subcompute(step,1,a1,a2);
return ;
}
int mid=(tree[step].l+tree[step].r)>>1;
if(h2<=mid)
{
compute(step<<1,h1,h2,a1,a2);
}
else
{
if(h1>mid)
{
compute(step<<1|1,h1,h2,a1,a2);
}
else
{
compute(step<<1,h1,mid,a1,a2);
compute(step<<1|1,mid+1,h2,a1,a2);
}
}
}
int main()
{
int n,h,x2,y2,x1,y1,r;
char ch[10];
double a,f,x,y;
int sum;
while(scanf("%d",&n))
{
if(n==0)
break;
build(1,100,200,0,1000);
while(n--)
{
scanf("%s",ch);
if(ch[0]=='I')
{
scanf("%d%lf%lf",&h,&a,&f);
r=(int)(a*10);
sum=(int)(f*10);
updata(1,h,r,sum);
}
else
{
scanf("%d%d%lf%lf",&x1,&y1,&x,&y);
x2=(int)(x*10);
y2=(int)(y*10);
if(x1>y1)
swap(x1,y1);
if(x2>y2)
swap(x2,y2);
Max=0;
compute(1,x1,y1,x2,y2);
double ans=Max/10.0;
if(ans<=0)
{
printf("-1\n");
}
else
{
printf("%.1lf\n",ans);
}
}
}
}
return 0;
}
终于对二维线段树有了一个大概的理解!
二维线段树有两种建树方法:
1:树中有树,就是建立母树,再在母树中建立子树
2:四分思想,每个节点有四个孩子
我用的是第一种方法