hdu 1823 二维线段树点更新

题意:

中文题


解题思路:

利用二维线段树的点更新即可


注意:

二维线段树的在点更新时,需先更新局部的子区间,然后更新全局区间


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXN0 102
#define MAXN1 1002
typedef struct node1{
    int yL,yR;
    int L;
    bool equal(int cc,int dd){
        if(yL==cc&&yR==dd){
            return true;
        }
        return false;
    }
    void set(int cc,int dd,int ee){
        yL = cc;
        yR = dd;
        L = ee;
    }
};
typedef struct node2{
    int xL,xR;
    //int L;
    bool equal(int cc,int dd){
        if(xL==cc&&xR==dd){
            return true;
        }
        return false;
    }
    node1 subTr[MAXN1<<2];
};
node2 Tr[MAXN0<<2];
int cnt;
int max(int aa,int bb){
    return aa>bb?aa:bb;
}
void buildsubTr(int ind1,int ind2,int L2,int R2){
    Tr[ind1].subTr[ind2].set(L2, R2,-1);
    if(L2==R2)return;
    int mid = (L2+R2)>>1;
    buildsubTr(ind1, ind2<<1, L2, mid);
    buildsubTr(ind1, (ind2<<1)+1, mid+1, R2);
}
void buildTr(int ind1,int L1,int R1,int L2,int R2){
    //if(L1>R1||L2>R2)return;
    Tr[ind1].xL = L1;
    Tr[ind1].xR = R1;
    buildsubTr(ind1,1,L2,R2);
    if(L1==R1){
        return;
    }
    //if(L1!=R1){
    //        printf("%d %d\n",L1,R1);
    int m = (L1+R1)>>1;
    buildTr(ind1<<1, L1, m, L2, R2);
    buildTr((ind1<<1)+1, m+1, R1, L2, R2);
    
}
void Insertsub(int ind1,int ind2,int L2,int R2,int L){
    if(Tr[ind1].subTr[ind2].equal(L2, R2)){
        Tr[ind1].subTr[ind2].L = max(Tr[ind1].subTr[ind2].L,L);
        return;
    }
    
    if(Tr[ind1].subTr[ind2].yL!=Tr[ind1].subTr[ind2].yR){
        int mid;
        mid = (Tr[ind1].subTr[ind2].yL+Tr[ind1].subTr[ind2].yR)>>1;
        if(R2<=mid){
            Insertsub(ind1,ind2<<1,L2,R2,L);
        }
        else if(mid<L2){
            Insertsub(ind1,(ind2<<1)+1,L2,R2,L);
        }
        else {
            Insertsub(ind1,ind2<<1,L2,mid,L);
            Insertsub(ind1,(ind2<<1)+1,mid+1,R2,L);
        }
        Tr[ind1].subTr[ind2].L = max(Tr[ind1].subTr[ind2<<1].L,Tr[(ind1)].subTr[(ind2<<1)+1].L);
    }
}
void Insert(int ind1,int L1,int R1,int L2,int R2,int L){
    if(Tr[ind1].equal(L1, R1)){
        //Tr[ind1][ind2].L = max(Tr[ind1][ind2].L,L);
        Insertsub(ind1, 1, L2, R2, L);
        return;
    }
    Insertsub(ind1, 1, L2, R2, L);
    int mid;
    if(Tr[ind1].xL!=Tr[ind1].xR){
        mid = (Tr[ind1].xL+Tr[ind1].xR)>>1;
        if(R1<=mid){
            Insert(ind1<<1,L1,R1,L2,R2,L);
        }
        else if(mid<L1){
            Insert((ind1<<1)+1,L1,R1,L2,R2,L);
        }
        else {
            Insert(ind1<<1,L1,mid,L2,R2,L);
            Insert((ind1<<1)+1,mid+1,R1,L2,R2,L);
        }
        Tr[ind1].subTr[1].L = max(Tr[ind1<<1].subTr[1].L,Tr[(ind1<<1)+1].subTr[1].L);
    }
}
int Querysub(int ind1,int ind2,int L2,int R2){
    if(Tr[ind1].subTr[ind2].equal(L2, R2)){
        //Tr[ind1].subTr[ind2].L = max(Tr[ind1].subTr[ind2].L,L);
        return Tr[ind1].subTr[ind2].L ;
    }
    int mid;
    if(Tr[ind1].subTr[ind2].yL!=Tr[ind1].subTr[ind2].yR){
        mid = (Tr[ind1].subTr[ind2].yL+Tr[ind1].subTr[ind2].yR)>>1;
        if(R2<=mid){
            return  Querysub(ind1,ind2<<1,L2,R2);
        }
        else if(mid<L2){
            return  Querysub(ind1,(ind2<<1)+1,L2,R2);
        }
        else {
            return max(Querysub(ind1,ind2<<1,L2,mid),Querysub(ind1,(ind2<<1)+1,mid+1,R2));
            
        }
    }
    return Tr[ind1].subTr[ind2].L;
}
int Query(int ind1,int L1,int R1,int L2,int R2){
    if(Tr[ind1].equal(L1, R1)){
        //Tr[ind1][ind2].L = max(Tr[ind1][ind2].L,L);
        return Querysub(ind1, 1, L2, R2);
        //return;
    }
    int mid;
    if(Tr[ind1].xL!=Tr[ind1].xR){
        mid = (Tr[ind1].xL+Tr[ind1].xR)>>1;
        if(R1<=mid){
            return  Query(ind1<<1,L1,R1,L2,R2);
        }
        else if(mid<L1){
            return  Query((ind1<<1)+1,L1,R1,L2,R2);
        }
        else {
            return max(Query(ind1<<1,L1,mid,L2,R2),Query((ind1<<1)+1,mid+1,R1,L2,R2));
            
        }
        // Tr[ind1].subTr[1].L = max(Tr[ind1<<1].subTr[1].L,Tr[(ind1<<1)+1].subTr[1].L);
    }
    return Tr[ind1].subTr[1].L;
}
void swap(int &aa,int &bb){
    int tmp = aa;
    aa = bb;
    bb = tmp;
}
int main(){
    int M;
    int  A,L,H,H1,H2,A1,A2,ans;
    double tA,tL,tA1,tA2;
    char str[1];
    //cnt = 0;
    // buildTr(1,1,1,101,1,1001);
    while(scanf("%d",&M)!=EOF){
        if(!M){
            break;
        }
        buildTr(1,1,101,1,1001);
        //scanf("");
        //printf("YES\n");
        for(int i=0;i<M;++i){
            scanf("%s",str);
            if(str[0]=='Q'){
                scanf("%d%d%lf%lf",&H1,&H2,&tA1,&tA2);
                A1 = tA1*10;
                A2 = tA2*10;
                //                if(H1>H2||A1>A2){
                //                    printf("-1\n");
                //                    continue;
                //                }
                H1-=99;
                H2-=99;
                A1++;
                A2++;
                if(H1>H2){
                    swap(H1,H2);
                }
                if(A1>A2){
                    swap(A1,A2);
                }
                ans = Query(1,H1,H2,A1,A2);
                if(ans==-1){
                    puts("-1");
                }
                else {
                    printf("%.1lf\n",(ans*1.0)/10);
                }
            }
            else{
                scanf("%d%lf%lf",&H,&tA,&tL);
                A = tA*10;
                L = tL*10;
                H-=99;
                A++;
                Insert(1,H,H,A,A,L);
            }
        }
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值