zoukankan      html  css  js  c++  java
  • [BZOJ 3224] [Tyvj 1728] 普通平衡树

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec
    Memory Limit: 128 MB

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-1e7,1e7]
    【题解】
    平衡树模板题目。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=100010;
      4 int fa[N],ch[N][2],root,k[N],ind=0,size[N];
      5 void zig(int x) {  
      6     int y=fa[x],z=fa[y];  
      7     fa[y]=x;
      8     fa[x]=z;  
      9     ch[y][0]=ch[x][1],fa[ch[x][1]]=y,ch[x][1]=y;  
     10     if (y==ch[z][0]) ch[z][0]=x;  
     11     else ch[z][1]=x;  
     12     size[y]=size[ch[y][0]]+size[ch[y][1]]+1; 
     13 }  
     14 void zag(int x) {  
     15     int y=fa[x],z=fa[y];  
     16     fa[y]=x,fa[x]=z; 
     17     ch[y][1]=ch[x][0],fa[ch[x][0]]=y,ch[x][0]=y;  
     18     if (y==ch[z][0]) ch[z][0]=x;  
     19     else ch[z][1]=x;  
     20     size[y]=size[ch[y][0]]+size[ch[y][1]]+1; 
     21 }  
     22 void splay(int x,int s) {
     23     while (fa[x]!=s) {  
     24         int y=fa[x],z=fa[y];  
     25         if (z==s) {  
     26             if (x==ch[y][0]) zig(x);  
     27             else zag(x);  
     28             break;  
     29         }  
     30         if (y==ch[z][0]) {
     31             if (x==ch[y][0]) zig(y),zig(x);  
     32             else zag(x),zig(x);  
     33         }  
     34         else {  
     35             if (x==ch[y][1]) zag(y),zag(x);  
     36             else zig(x),zag(x);  
     37         }  
     38     }  
     39     size[x]=size[ch[x][0]]+size[ch[x][1]]+1; 
     40     if (s==0) root=x;
     41 }  
     42 inline void newnode(int &x,int fax,int key) {
     43     x=++ind;
     44     ch[x][0]=ch[x][1]=0;
     45     fa[x]=fax;
     46     k[x]=key;
     47 }
     48 inline int search(int w) {
     49     int p,x=root;
     50     while(x) {
     51         p=x;
     52         if(k[x]>w) x=ch[x][0];
     53         else x=ch[x][1];
     54     }
     55     return p;
     56 }
     57 inline void ins(int w){
     58     if (root==0) {
     59         newnode(root,0,w);
     60         return ;
     61     }
     62     int i=search(w);
     63     if(w<k[i]) newnode(ch[i][0],i,w);
     64     else newnode(ch[i][1],i,w);
     65     splay(ind,0);
     66 }
     67 int getsm(int w) {
     68     int x=root,ans=ind+1;
     69     while(x) {
     70         if (k[x]>w) {x=ch[x][0];continue;}
     71         if (k[x]<w) {x=ch[x][1];continue;}
     72         if (k[x]==w) {
     73             ans=x;
     74             x=ch[x][0];
     75         }
     76     }
     77     if (ans==ind+1) return -1;
     78     return ans;
     79 }
     80 inline int getmax(int x) {while(ch[x][1]) x=ch[x][1]; return x;}
     81 inline int getmin(int x) {while(ch[x][0]) x=ch[x][0]; return x;}
     82 inline int getpre(int x) {return getmax(ch[root][0]);}
     83 inline int getnext(int x) {return getmin(ch[root][1]);}
     84 inline void del(int w) {
     85     int x=getsm(w);
     86     splay(x,0);
     87     int pp=getpre(x),nn=getnext(x);
     88     splay(pp,0);splay(nn,root);
     89     int y=fa[x];
     90     fa[x]=0;
     91     if(x==ch[y][0]) ch[y][0]=0;
     92     else ch[x][0]=0;
     93     size[y]=size[ch[y][0]]+size[ch[y][1]]+1;
     94     size[root]=size[ch[root][0]]+size[ch[root][1]]+1;
     95 }
     96 inline int ffind(int w) {
     97     int x=getsm(w);
     98     splay(x,0);
     99     return size[ch[x][0]];
    100 }
    101 int findkth(int x,int kth) {
    102     int s=size[ch[x][0]];
    103     if(kth==s+1) return k[x];
    104     if(s>=kth) return findkth(ch[x][0],kth);
    105     else return findkth(ch[x][1],kth-s-1);
    106 }
    107 int getp(int w) {
    108     int y=getsm(w);
    109     ins(w);
    110     if(y!=-1) splay(y,0);
    111     int ans=getmax(ch[root][0]);
    112     del(w);
    113     return k[ans];
    114 }
    115 int getn(int w) {
    116     ins(w);
    117     int ans=getmin(ch[root][1]);
    118     del(w);
    119     return k[ans];
    120 }
    121 int main() {
    122     int q;
    123     root=0;
    124     ins(-5000000);ins(5000000);
    125     scanf("%d",&q);  
    126     while (q--) {  
    127         int x,k;  
    128         scanf("%d%d",&x,&k);  
    129         if (x==1) ins(k);  
    130         else if (x==2) del(k);  
    131         else if (x==3) printf("%d
    ",ffind(k));  
    132         else if (x==4) printf("%d
    ",findkth(root,k+1));  
    133         else if (x==5) printf("%d
    ",getp(k));  
    134         else if (x==6) printf("%d
    ",getn(k));  
    135     }
    136     return 0;
    137 }
    View Code

    还是习惯分开来写Zig-Zag

  • 相关阅读:
    买卖股票的最佳时机
    删除排序数组中的重复数字
    软件工程第五次作业:个人总结
    软件工程第二次作业——结对编程
    第一次软件工程作业补充plus
    第二次(四则运算,)
    我的第一次
    软件工程--个人总结
    软件工程第二次作业—结对编程
    软件工程第一次作业补充
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/bzoj3224.html
Copyright © 2011-2022 走看看