您的位置:首页 > 其它

hdu1823 Luck and Love 二维线段树

2013-01-03 18:52 465 查看
首先发表下做完后的感受:这题真他妈操蛋!!!



一个简单的二维线段树,搞了一下午啊啊。。

思路:首先根据身高建一棵线段树,然后在每个节点上再以活泼度建一棵线段树,并记录每个区间的最大缘分值。

重点说细节了:在查询时可能会有A1>A2,H1>H2;然后就是插入数据时可能会有缘分值为0的数据,所以初始化时不要初始化为0;可能会插入身高和活泼度相同但缘分值不同的数据,因此还需要比较一下;最后一点,我写(int)(A*10)竟然会wrong,最后看了讨论改为(int)((A+eps)*10)就过了。

#include <iostream>
#include<cstdio>

using namespace std;
const double eps=1e-6;//看了讨论后加的。。。
struct subtree//活泼度
{
int l, r;
double MAXL;//最大缘分值
};

struct tree//身高
{
int l, r;
struct subtree node[4100];
}p[410];

void createnode(int i,int l,int r,int rt)
{
p[i].node[rt].l=l;
p[i].node[rt].r=r;
p[i].node[rt].MAXL=-1.0;
if(l==r)
return;
int mid=(l+r)>>1;
createnode(i,l,mid,rt<<1|1);
createnode(i,mid+1,r,(rt<<1)+2);
}

void createtree(int l,int r,int rt)
{
p[rt].l=l;
p[rt].r=r;
createnode(rt,0,1000,0);
if(l==r)
return;
int mid=(l+r)>>1;
createtree(l,mid,rt<<1|1);
createtree(mid+1,r,(rt<<1)+2);
}

void insertnode(int i,int A,double L,int rt)
{
if(p[i].node[rt].l==p[i].node[rt].r&&p[i].node[rt].l==A)
{
if(p[i].node[rt].MAXL<L)
p[i].node[rt].MAXL=L;
return;
}
int mid=(p[i].node[rt].l+p[i].node[rt].r)>>1;
if(A<=mid)
insertnode(i,A,L,rt<<1|1);
else
insertnode(i,A,L,(rt<<1)+2);
p[i].node[rt].MAXL=max(p[i].node[rt<<1|1].MAXL,p[i].node[(rt<<1)+2].MAXL);
}

void insert(int H,int A,double L,int rt)
{
insertnode(rt,A,L,0);//在包含该值的节点上都要插入
if(p[rt].l==H&&p[rt].l==p[rt].r)
return;
int mid=(p[rt].l+p[rt].r)>>1;
if(H<=mid)
insert(H,A,L,rt<<1|1);
else
insert(H,A,L,(rt<<1)+2);
}

float querynode(int i,int A1,int A2,int rt)
{
if(p[i].node[rt].l==A1&&p[i].node[rt].r==A2)
return p[i].node[rt].MAXL;
int mid=(p[i].node[rt].l+p[i].node[rt].r)>>1;
if(A2<=mid)
return querynode(i,A1,A2,rt<<1|1);
else if(A1>mid)
return querynode(i,A1,A2,(rt<<1)+2);
else
return max(querynode(i,A1,mid,rt<<1|1),querynode(i,mid+1,A2,(rt<<1)+2));
}

float query(int H1,int H2,int A1,int A2,int rt)
{
if(p[rt].l==H1&&p[rt].r==H2)
return querynode(rt,A1,A2,0);
int mid=(p[rt].l+p[rt].r)>>1;
if(H2<=mid)
return query(H1,H2,A1,A2,rt<<1|1);
else if(H1>mid)
return query(H1,H2,A1,A2,(rt<<1)+2);
else
return max(query(H1,mid,A1,A2,rt<<1|1),query(mid+1,H2,A1,A2,(rt<<1)+2));
}

int main()
{
int m,H1,H2;
double A1,A2,L;
char op[3];
while(scanf("%d",&m),m)
{
createtree(0,100,0);
while(m--)
{
scanf("%s",op);
if(op[0]=='I')
{
scanf("%d%lf%lf",&H1,&A1,&L);
H1-=100;//都统一减掉100,这样H的范围就是0-100
insert(H1,int((A1+eps)*10),L,0);
}
else
{
scanf("%d%d%lf%lf",&H1,&H2,&A1,&A2);
if(H1>H2)
swap(H1,H2);
if(A1>A2)
swap(A1,A2);
H1-=100;H2-=100;
//不知道此处为何非要加上eps
double ans=query(H1,H2,int((A1+eps)*10),int((A2+eps)*10),0);
if(ans==-1.0)
printf("-1\n");
else
printf("%.1lf\n",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: