【二维线段树】HDU 1823

 很裸的一道二维线段树,第一次做,其实二维的线段树也就是树套树,先一维再第二维,第一、二维的操作都很类似。

说回hdu这道题,有点水,提交的时候记得交c++,g++会wa死你!

#define N 210
struct node{
    int al,ar;
    double mx;
};
struct node1{
    int hl,hr;
    node subt[4000];
}t[N*4];
void build_sub(int id,int rt,int ll,int rr){//第二维建树
    t[id].subt[rt].al = ll;
    t[id].subt[rt].ar = rr;
    t[id].subt[rt].mx = -1.0;
    if(ll == rr){
        return ;
    }
    int mid = (ll+rr)>>1;
    build_sub(id,rt<<1,ll,mid);
    build_sub(id,rt<<1|1,mid+1,rr);
}
void build(int id,int l,int r,int ll,int rr){//一维建树
    t[id].hl = l;
    t[id].hr = r;
    build_sub(id,1,ll,rr);
    if(l == r)return ;
    int mid = (l+r)>>1;
    build(id<<1,l,mid,ll,rr);
    build(id<<1|1,mid+1,r,ll,rr);
}
void add_sub(int id,int rt,int act,double love){//第二维插入
    t[id].subt[rt].mx = max(love,t[id].subt[rt].mx);
    if(t[id].subt[rt].al == t[id].subt[rt].ar)return ;
    int mid = (t[id].subt[rt].al+t[id].subt[rt].ar)>>1;
    if(act<=mid)add_sub(id,rt<<1,act,love);
    else add_sub(id,rt<<1|1,act,love);
    t[id].subt[rt].mx = max(t[id].subt[rt<<1].mx, t[id].subt[rt<<1|1].mx);
}
void add(int id,int h,int act,double love){//第一位插入
    add_sub(id,1,act,love);
    if(t[id].hl ==  t[id].hr){
        return ;
    }
    int mid = (t[id].hl+t[id].hr)>>1;
    if(h<=mid)add(id<<1,h,act,love);
    else add(id<<1|1,h,act,love);
}
double sear(int id,int rt,int ll,int rr){//查找第二维
    if(t[id].subt[rt].al==ll && t[id].subt[rt].ar==rr){
        return t[id].subt[rt].mx;
    }
    int mid = (t[id].subt[rt].al+t[id].subt[rt].ar)>>1;
    if(rr<=mid)return sear(id,rt<<1,ll,rr);
    else if(ll>mid)return sear(id,rt<<1|1,ll,rr);
    else return max(sear(id,rt<<1,ll,mid), sear(id,rt<<1|1,mid+1,rr));
}
double query(int id,int l,int r,int ll,int rr){//查找第二维
    if(t[id].hl==l && t[id].hr==r){
        return sear(id,1,ll,rr);
    }
    int mid = (t[id].hl+t[id].hr)>>1;
    if(r<=mid)return query(id<<1,l,r,ll,rr);
    else if(l>mid)return query(id<<1|1,l,r,ll,rr);
    else return max(query(id<<1,l,mid,ll,rr), query(id<<1|1,mid+1,r,ll,rr));
}
int main(){
    int n;
    while(scanf("%d",&n) && n){
        int i,j;
        build(1,100,200,0,1000);
        char str[3];
        while(n--){
            scanf("%s",str);
            if(str[0] == 'I'){
                double x,y;
                int h;
                scanf("%d%lf%lf",&h,&x,&y);
                int xx = x*10;
                add(1,h,xx,y);
            } else {
                int h1,h2;
                double x1,x2;
                int y1,y2;
                scanf("%d%d%lf%lf",&h1,&h2,&x1,&x2);
                y1 = x1*10,y2 = x2*10;
                if(h1>h2)swap(h1,h2);//trick!
                if(y1>y2)swap(y1,y2);
                double ans = query(1,h1,h2,y1,y2);
                if(ans == -1.0)printf("-1\n");
                else printf("%.1lf\n",ans);
            }
        }
    }
    return 0;
}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值