2维线段树----杭电ACM 1823 Luck and Love
第一次碰见2维的线段树!也不晓得怎么做,就自己墨迹着一步一步写下去,边想边写,其实二维和一维一样,就是镶嵌了个子线段树,写了一下午,提交还是WA!改到现在终于A了!
思路:
(1):线段树种嵌套个子线段树,子线段树处理方法和一维的一样
(2):将活跃度和缘分值都扩大10倍变成整数,因为它们只有一位小数,所以扩大10倍即可
这题有4个注意点:
(1):如果用的G++编译器的话,处理浮点的时候 # define eps 1e-4 a1+=eps;再将浮点转换成整数,如果用C++编译器则可以不用
(2):在更新结点的时候要注意,只有当当前输入的缘分值大于结点的缘分值,才将结点的缘分值更新,否则不更新,愚人就是错这,找了一晚上
(3):题目中4个浮点数,其实只有2个浮点数,身高的2个值均为整数
(4):身高h1有可能大于h1,活跃度也是如此,要做下交换处理
写的比较乱!!见谅~~~
//c++
# include<cstdio>
# include<iostream>
using namespace std;
const int MAX=1010;
# define eps 1e-4
struct sub_node
{
int ll;
int rr;
int max;
};
struct node
{
int r;
int l;
sub_node sub_tree[MAX*4];
}tree[110*4];
inline int max(int a,int b)
{
return a>b?a:b;
}
void Sub_Bulid(int rt,int sub_rt,int l,int r)
{
int mid;
tree[rt].sub_tree[sub_rt].ll=l;
tree[rt].sub_tree[sub_rt].rr=r;
tree[rt].sub_tree[sub_rt].max=-1;
if(r==l)
return;
mid=(r+l)/2;
Sub_Bulid(rt,2*sub_rt,l,mid);
Sub_Bulid(rt,2*sub_rt+1,mid+1,r);
}
void Bulid(int rt,int l,int r)
{
int mid;
tree[rt].l=l;
tree[rt].r=r;
Sub_Bulid(rt,1,0,1000);
if(l==r)
return;
mid=(l+r)/2;
Bulid(2*rt,l,mid);
Bulid(2*rt+1,mid+1,r);
}
void sub_change(int rt,int sub_rt,int a,int l)
{
int mid;
if(tree[rt].sub_tree[sub_rt].ll==tree[rt].sub_tree[sub_rt].rr)
{
if(tree[rt].sub_tree[sub_rt].max<l)
tree[rt].sub_tree[sub_rt].max=l;
return;
}
mid=(tree[rt].sub_tree[sub_rt].ll+tree[rt].sub_tree[sub_rt].rr)/2;
if(a<=mid)
sub_change(rt,2*sub_rt,a,l);
else
sub_change(rt,2*sub_rt+1,a,l);
tree[rt].sub_tree[sub_rt].max=max(tree[rt].sub_tree[2*sub_rt].max,tree[rt].sub_tree[2*sub_rt+1].max);
}
void change(int rt,int h,int a,int l)
{
int mid;
if(tree[rt].l<=h&&tree[rt].r>=h)
sub_change(rt,1,a,l);
if(tree[rt].l==tree[rt].r)
return;
mid=(tree[rt].l+tree[rt].r)/2;
if(h<=mid)
change(2*rt,h,a,l);
else
change(2*rt+1,h,a,l);
}
int sub_Query(int rt,int sub_rt,int a1,int a2)
{
int mid;
if(tree[rt].sub_tree[sub_rt].ll>=a1&&tree[rt].sub_tree[sub_rt].rr<=a2)
return tree[rt].sub_tree[sub_rt].max;
mid=(tree[rt].sub_tree[sub_rt].ll+tree[rt].sub_tree[sub_rt].rr)/2;
if(a2<=mid)
return sub_Query(rt,2*sub_rt,a1,a2);
else if(a1>mid)
return sub_Query(rt,2*sub_rt+1,a1,a2);
else
return max(sub_Query(rt,2*sub_rt,a1,a2),sub_Query(rt,2*sub_rt+1,a1,a2));
}
int Query(int rt,int h1,int h2,int a1,int a2)
{
int mid;
if(tree[rt].l>=h1&&tree[rt].r<=h2)
return sub_Query(rt,1,a1,a2);
mid=(tree[rt].l+tree[rt].r)/2;
if(h2<=mid)
return Query(2*rt,h1,h2,a1,a2);
else if(h1>mid)
return Query(2*rt+1,h1,h2,a1,a2);
else
return max(Query(2*rt,h1,h2,a1,a2),Query(2*rt+1,h1,h2,a1,a2));
}
int main()
{
int i,m,res,a,l,t,h,h1,h2,A1,A2;
char s[5];
double a1,l1,a2;
while(scanf("%d",&m)!=EOF&&m)
{
Bulid(1,100,200);
for(i=1;i<=m;i++)
{
scanf("%s",s);
if(s[0]=='I')
{
scanf("%d%lf%lf",&h,&a1,&l1);
a=(int)(a1*10);
l=(int)(l1*10);
change(1,h,a,l);
}
else if(s[0]=='Q')
{
scanf("%d%d%lf%lf",&h1,&h2,&a1,&a2);
A1=(int)(a1*10);
A2=(int)(a2*10);
if(h1>h2)
{
t=h1;
h1=h2;
h2=t;
}
if(A1>A2)
{
t=A1;
A1=A2;
A2=t;
}
res=Query(1,h1,h2,A1,A2);
if(res!=-1)
printf("%.1f\n",(double)(res*1.0/10));
else
printf("-1\n");
}
}
}
return 0;
}