//4681418 2011-09-30 12:26:14 Accepted 1823 140MS 7520K 3762 B C++ nkhelloworld
//4681419 2011-09-30 12:26:40 Accepted 1823 203MS 7588K 3762 B G++ nkhelloworld
/*
二维线段树,一个线段树中套一个线段树,求区间最大值
再次强调要注意区间范围是不是反着的,如h1 > h2时应swap
注意读入浮点数的时候可能产生精度误差,*10再转int可能就错了
此题,如果不加eps,在C++下可以AC,在G++下是WA
*/
#include <cstdio>
#include <iostream>
#define eps 1e-4
using namespace std;
#define MAXH 110
#define MAXA 1010
struct SUBTREE
{
    int lt,rt;
    double maxval;
};
struct MAINTREE
{
    int lt,rt;
    SUBTREE subtree[MAXA*4];
}tree[MAXH*4];
void buildsubtree(int paroot,int root,int lt,int rt)
{
    tree[paroot].subtree[root].lt = lt;
    tree[paroot].subtree[root].rt = rt;
    tree[paroot].subtree[root].maxval = -1.0;
    if(lt == rt)    return ;
    int mid = (lt + rt)>>1;
    buildsubtree(paroot,root<<1,lt,mid);
    buildsubtree(paroot,root<<1|1,mid+1,rt);
}
void buildmaintree(int root,int lt,int rt)
{
    tree[root].lt = lt; tree[root].rt = rt;
    buildsubtree(root,1,0,1000);
    if(lt == rt)    return ;
    int mid = (lt + rt)>>1;
    buildmaintree(root<<1,lt,mid);
    buildmaintree(root<<1|1,mid+1,rt);
}
void update2(int paroot,int root,int h,int active,double love)
{
    if(tree[paroot].subtree[root].maxval < love)    tree[paroot].subtree[root].maxval = love;
    if(tree[paroot].subtree[root].lt == tree[paroot].subtree[root].rt)  return ;
    int mid = (tree[paroot].subtree[root].lt + tree[paroot].subtree[root].rt)>>1;
    if(active <= mid)       update2(paroot,root<<1,h,active,love);
    else                            update2(paroot,root<<1|1,h,active,love);
}

void update(int root,int h,int active,double love)
{
    update2(root,1,h,active,love);
    if(tree[root].lt == tree[root].rt)  return ;
    int mid = (tree[root].lt + tree[root].rt)>>1;
    if(h <= mid)    update(root<<1,h,active,love);
    else                update(root<<1|1,h,active,love);
}

double query2(int paroot,int root,int h1,int h2,int a1,int a2)
{
    if(tree[paroot].subtree[root].lt == a1 && tree[paroot].subtree[root].rt == a2)
        return tree[paroot].subtree[root].maxval;
    int mid = (tree[paroot].subtree[root].lt + tree[paroot].subtree[root].rt)>>1;
    if(a2 <= mid)
        return query2(paroot,root<<1,h1,h2,a1,a2);
    else if(a1 > mid)
        return query2(paroot,root<<1|1,h1,h2,a1,a2);
    else
        return max(query2(paroot,root<<1,h1,h2,a1,mid), query2(paroot,root<<1|1,h1,h2,mid+1,a2) );
}

double query(int root,int h1,int h2,int a1,int a2)
{
    if(tree[root].lt == h1 && tree[root].rt == h2)  return query2(root,1,h1,h2,a1,a2);
    int mid = (tree[root].lt + tree[root].rt)>>1;
    if(h2 <= mid)   return query(root<<1,h1,h2,a1,a2);
    else if(h1 > mid)   return query(root<<1|1,h1,h2,a1,a2);
    else    return max( query(root<<1,h1,mid,a1,a2), query(root<<1|1,mid+1,h2,a1,a2) );
}

int main()
{
    int m,i,j,h1,h2;
    double a,love,a1,a2;
    char op[5];
    while(scanf("%d",&m),m)
    {
        buildmaintree(1,0,100);
        while(m--)
        {
            scanf("%s",op);
            if(op[0] == 'I')
            {
                scanf("%d%lf%lf",&h1,&a,&love);
                h1 = h1 - 100;
                a += eps;
                update(1,h1,(int)(a*10),love);
            }
            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;
                a1 += eps;  a2 += eps;
                double ans = query(1,h1,h2,(int)(a1*10),(int)(a2*10));
                if(ans < 0)
                    printf("-1\n");
                else
                    printf("%.1f\n",ans);
            }
        }
    }
    return 0;
}

posted on 2011-09-30 12:44  NKHe!!oWor!d  阅读(167)  评论(0编辑  收藏  举报