• hdu5107 线段树


    hdu 5107 这题说的是给了一个二维的 平面, 平面内有30000个点每个点都有自己的高度,然后又30000次的查询,每次查询给的是(X,Y,K), 要求出set(x,y){x,y|x<=X&&y<=Y } 的所有点,中第K 大的数是多少,存在输出该高度,允许重复; 否者输出-1,。

      本来想用主席树做,发现,找前节点还是比较麻烦的。再加上k<=10 还是比较小的, 然后我们按照y设置为线段树的页节点,然后发现每个页节点最多存10种高度,然后他们的父节点只需要合并孩子的两个长度为10的高度数组, 我们将所有的点包括询问的点进行离散化,按x按y从小到大排序, 离散化后查询在数组中, 保证了x一定小于等于当前要插入或者是查询的点,这样就可以减少对于x的处理,然后接下来就是让该点的y找到相应的叶节点,然后用该建筑物的h更新叶节点。 如果是查询就查寻(1,IDX(P[i].y))

    #include <algorithm>
    #include <cstdio>
    #include <string.h>
    #include <vector>
    using namespace std;
    const int maxn=30005;
    typedef int ll;
    struct point{
        ll x,h[11];
    }AN;
    struct build{
        ll x,y,h;
        ll id,op;
        bool operator < ( const build A ) const {
             return x<A.x||(x==A.x&&y<A.y)||(x==A.x&&y==A.y&&op<A.op)||(x==A.x&&y==A.y&&op==A.op&&id<A.id);
        }
    }P[maxn*2];
    ll Y[maxn*2];
    ll ans[maxn];
    ll Va,loc,cL,cR,tim;
    struct Itree{
       point V[maxn*4*2];
       void build(int o,int L, int R){
            V[o].x=0;
            if(L==R) return ;
            int mid =(L+R)/2;
            build(o*2, L, mid );
            build(o*2+1, mid+1, R);
       }
       void inser(int o ){
           int i=0;
           for( i=0; i<V[o].x; i++){
             if(Va<V[o].h[i]) break;
           }
           if(i==10) return;
           for(int j = V[o].x; j>i; --j)
             V[o].h[j]=V[o].h[j-1];
           V[o].h[i]=Va;
           V[o].x=min(V[o].x+1,10);
       }
       point maintain( point o1, point o2){
          point ans;
           int i,j,k;
           i=j=k=0;
           while( (i<o1.x||j<o2.x )&&( k<10) ){
                 if(j>=o2.x ||( i<o1.x && o1.h[i]<o2.h[j]  ) )
                      ans.h[k++] = o1.h[i++];
                 else ans.h[k++] = o2.h[j++];
           }
           ans.x=k;
           return ans;
       }
       void update(int o, int L, int R){
            if(L==R){
              inser(o); return ;
            }
            int mid = (L+R)>>1;
            if(loc<=mid) update(o*2,L, mid);
            else update(o*2+1,mid+1,R);
            V[o]=maintain(V[o*2], V[o*2+1]);
       }
       void query(int o, int L, int R){
             if(cL<=L && R<= cR){
                if(tim==0){
                     tim=1;
                     AN=V[o];
                }else {
                    AN=maintain(AN,V[o]);
                }
                return ;
             }
             int mid = (L+R)>>1;
             if(cL<=mid) query(o*2,L,mid);
             if(cR>mid) query(o*2+1, mid+1, R);
    
       }
    }T;
    int main()
    {
       int n,m;
       while(scanf("%d%d",&n,&m)==2){
            for(int i=0; i<n; ++i){
                scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].h);
                 P[i].id=i;
                P[i].op=0;
                Y[i]=P[i].y;
            }
            for(int i=0; i<m; ++i){
                 scanf("%d%d%d",&P[i+n].x,&P[i+n].y,&P[i+n].h);
                 P[i+n].id=n+i;
                 P[i+n].op=1;
                 Y[i+n]=P[i+n].y;
            }
            sort(Y,Y+n+m);
            int Ynum = unique(Y,Y+n+m)-Y;
            T.build(1,1,Ynum);
            sort(P,P+n+m);
            for(int i=0; i<n+m; ++i){
                 if(P[i].op==0){
                     loc = lower_bound(Y,Y+Ynum,P[i].y)-Y+1;
                      Va= P[i].h;
                      T.update(1, 1, Ynum);
                 }else{
                     tim=0;
                     cR = lower_bound(Y,Y+Ynum,P[i].y)-Y+1;
                     cL=1;
                     T.query(1,1,Ynum);
                     if(AN.x>=P[i].h){
                         ans[P[i].id-n]=AN.h[ P[i].h-1 ];
                     } else{
                         ans[P[i].id-n]=-1;
                     }
                 }
            }
            for(int i=0; i<m; ++i)
                 printf("%d
    ",ans[i]);
       }
       return 0;
    }
    View Code
  • 相关阅读:
    python
    mysql 操作
    you-get 使用代理
    恢复本地策略组--用于启动项管理等
    bat批处理——获取文件夹下所有文件名/重命名
    cmd--set用法,下次补充实例
    bat+7z批量压缩"文件夹"
    Excel提取字符串示例
    cron
    AIX修改用户密码登录不成功案例分享
  • 原文地址:https://www.cnblogs.com/Opaser/p/4116150.html
Copyright © 2020-2023  润新知