zoukankan      html  css  js  c++  java
  • 普通平衡树

    平衡树模板题,然而WA惨了qaq,不过对平衡树理解加深还是不错的

    原题:

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

    就是平衡树的个中操作没啥好说的= =,因为已经存在于平衡树中的权值也要插入,所以在每个节点上记录和这个节点重叠的个数,然后个中操作都很方便了

    不过还是WA惨了,原因有二:

    一曰:如果记录和节点重叠的个数,旋转的时候一定要把重叠的个数转移到size上,本来想size只是维护平衡的,没有考虑到还牵扯到rank和select,我还是太弱了qaq

    二曰:maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 maintainTMD也是关键字 

    要用Maintain或smaintain

    小技巧:

    else if(tree[x].lchild && !tree[x].rchild)  x=tree[x].lchild;

    else if(tree[x].rchild && !tree[x].lchild)  x=tree[x].rchild;

    可以把if(!tree[x].lchild && !tree[x].rchild)放在前面,然后上面的就可以简化为

    if(!(tree[x].lchild*tree[x].rchild))  x=tree[x].lchild+tree[x].rchild;

    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 using namespace std;
      7 const int oo=168430090;
      8 int read(){int z=0,mark=1;  char ch=getchar();
      9     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
     10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
     11     return z*mark;
     12 }
     13 int n;
     14 int wans[1100000],wtou=0;
     15 int q[1100000];
     16 struct dcd{int lchild,rchild,size,tvalue,ge;}tree[1110000];  int ttop=0,root=0;
     17 void left_rotate(int &x){
     18     int y=tree[x].rchild;
     19     tree[x].rchild=tree[y].lchild;
     20     tree[y].lchild=x;
     21     tree[y].size=tree[x].size;
     22     tree[x].size=tree[tree[x].lchild].size+tree[tree[x].rchild].size+tree[x].ge;//注意这里一定要把相同的个数带下去
     23     x=y;
     24 }
     25 void right_rotate(int &x){
     26     int y=tree[x].lchild;
     27     tree[x].lchild=tree[y].rchild;
     28     tree[y].rchild=x;
     29     tree[y].size=tree[x].size;
     30     tree[x].size=tree[tree[x].lchild].size+tree[tree[x].rchild].size+tree[x].ge;//本来想size只是维护平衡的,没有考虑到还牵扯到rank和select,我还是太弱了qaq
     31     x=y;
     32 }
     33 void Maintain(int &x,bool flag){
     34     if(!flag){
     35         if(tree[tree[tree[x].lchild].lchild].size>tree[tree[x].rchild].size)  right_rotate(x);
     36         else if(tree[tree[tree[x].lchild].rchild].size>tree[tree[x].rchild].size)  left_rotate(tree[x].lchild),right_rotate(x);
     37         else  return ;
     38     }
     39     else{
     40         if(tree[tree[tree[x].rchild].rchild].size>tree[tree[x].lchild].size)  left_rotate(x);
     41         else if(tree[tree[tree[x].rchild].lchild].size>tree[tree[x].lchild].size)  right_rotate(tree[x].rchild),left_rotate(x);
     42         else  return ;
     43     }
     44     Maintain(tree[x].lchild,false),Maintain(tree[x].rchild,true);
     45     Maintain(x,1),Maintain(x,0);
     46 }
     47 void insert(int &x,int z){
     48     if(!x){
     49         x=++ttop;
     50         tree[x].size=tree[x].ge=1;
     51         tree[x].lchild=tree[x].rchild=0;
     52         tree[x].tvalue=z;
     53     }
     54     else{
     55         tree[x].size++;
     56         if(tree[x].tvalue==z){  tree[x].ge++;  return; }
     57         else if(z<tree[x].tvalue)  insert(tree[x].lchild,z);
     58         else  insert(tree[x].rchild,z);
     59         Maintain(x,z>tree[x].tvalue);
     60     }
     61 }
     62 void remove(int &x,int z){
     63     if(!x)  return ;
     64     tree[x].size--;
     65     if(z>tree[x].tvalue)  remove(tree[x].rchild,z);
     66     else  if(z<tree[x].tvalue)  remove(tree[x].lchild,z);
     67     else{
     68         if(tree[x].ge>1)  tree[x].ge--;
     69         else if(!tree[x].lchild && !tree[x].rchild)  x=0;
     70         else if(!(tree[x].lchild*tree[x].rchild))  x=tree[x].lchild+tree[x].rchild;
     71         else{
     72             int temp;
     73             if(tree[x].rchild){
     74                 temp=tree[x].rchild;
     75                 while(tree[temp].lchild)  temp=tree[temp].lchild;
     76             }
     77             else{
     78                 temp=tree[x].lchild;
     79                 while(tree[temp].rchild)  temp=tree[temp].rchild;
     80             }
     81             tree[x].tvalue=tree[temp].tvalue;
     82             remove(tree[x].rchild,tree[temp].tvalue);
     83         }
     84     }
     85 }
     86 int select(int &x,int y){
     87     if(!x)  return 0;
     88     if(y<=tree[tree[x].lchild].size)  return select(tree[x].lchild,y);
     89     else if(y>tree[tree[x].lchild].size+tree[x].ge)  return select(tree[x].rchild,y-tree[tree[x].lchild].size-tree[x].ge);
     90     else return tree[x].tvalue;
     91 }
     92 int rank(int &x,int y){
     93     if(!x)  return 0;
     94     if(y>tree[x].tvalue)  return tree[tree[x].lchild].size+tree[x].ge+rank(tree[x].rchild,y);
     95     else if(y<tree[x].tvalue)  return rank(tree[x].lchild,y);
     96     else  return tree[tree[x].lchild].size+1;
     97 }
     98 int predecessor(int &x,int _father,int z){
     99     if(!x)  return tree[_father].tvalue;
    100     if(z>tree[x].tvalue)  return predecessor(tree[x].rchild,x,z);
    101     else  return predecessor(tree[x].lchild,_father,z);
    102 }
    103 int successor(int &x,int _father,int z){
    104     if(!x)  return tree[_father].tvalue;
    105     if(z<tree[x].tvalue)  return successor(tree[x].lchild,x,z);
    106     else  return successor(tree[x].rchild,_father,z);
    107 }
    108 int main(){
    109     //freopen("ddd.in","r",stdin);
    110     //freopen("ddd.out","w",stdout);
    111     freopen("phs.in","r",stdin);
    112     freopen("phs.out","w",stdout);
    113     cin>>n;
    114     int _left,_right;
    115     while(n --> 0){//趋向于
    116         _left=read(),_right=read();
    117         if(_left==1)  insert(root,_right);
    118         else if(_left==2)  remove(root,_right);
    119         else if(_left==3)  printf("%d
    ",wans[++wtou]=rank(root,_right));
    120         else if(_left==4)  printf("%d
    ",wans[++wtou]=select(root,_right));
    121         else if(_left==5)  printf("%d
    ",wans[++wtou]=predecessor(root,0,_right));
    122         else  printf("%d
    ",wans[++wtou]=successor(root,0,_right));
    123         if(_left>=3)  q[wtou]=_left;
    124     }
    125     /*int _bans;
    126     for(int i=1;i<=wtou;i++){
    127         _bans=read();
    128         if(_bans!=wans[i]){
    129             cout<<_bans<<" "<<wans[i]<<" "<<q[i]<<endl;
    130         }
    131     }*/
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    Redis常用命令详细介绍(摘抄)
    线性表和链表
    TCP传输连接中的SYN、ACK、SEQ、AN分别是什么意思?他们所带的数字又是代表什么?
    redis默认有16个数据库
    常见问题
    jquery-table2excel 不导出列(隐藏列,或指定列)
    AngularJS 防止页面闪烁的方法
    如何做好需求分析
    IIS 一个服务器下不同站点操作共享文件夹
    批量修改 mysql数据库编码格式(Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='格式错误)
  • 原文地址:https://www.cnblogs.com/JSL2018/p/5986740.html
Copyright © 2011-2022 走看看