zoukankan      html  css  js  c++  java
  • 【模板】普通平衡树

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入x
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. x的前驱(前驱定义为小于x,且最大的数)
    6. x的后继(后继定义为大于x,且最小的数)

    输入格式

    第一行为nn,表示操作的个数,下面nn行每行有两个数optx,opt表示操作的序号(1opt6 )

    输出格式

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

    输入输出样例

    输入 #1

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

    输出 #1

    106465
    84185
    492737

    分析:
    当初做这题时我内心是崩溃的。。。(不过最近又敲一遍快多了,2个小时左右吧)

    CODE:
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 int root,size,m,ans;
      4 struct aaa{
      5     int l,r;
      6     int size;
      7     int weight;
      8     int fix;
      9     int val; 
     10 }tree[1000000];
     11 void update(int k){
     12     tree[k].size=tree[tree[k].l].size+tree[tree[k].r].size+tree[k].weight; 
     13     return;
     14 }
     15 void left_turn(int &k){
     16     int rson=tree[k].r;
     17     tree[k].r=tree[rson].l;
     18     tree[rson].l=k;
     19     tree[rson].size=tree[k].size;
     20     update(k);
     21     k=rson;
     22 }
     23 void right_turn(int &k){
     24     int lson=tree[k].l;
     25     tree[k].l=tree[lson].r;
     26     tree[lson].r=k;
     27     tree[lson].size=tree[k].size;
     28     update(k);
     29     k=lson;            
     30 }
     31 void insert(int &k,int x){
     32     if(k==0){
     33        size++;
     34        k=size;
     35        tree[k].size=1;
     36        tree[k].weight=1;
     37        tree[k].val=x;
     38        tree[k].fix=rand();
     39        return;
     40     }
     41     tree[k].size++;
     42     if(tree[k].val==x){
     43         tree[k].weight++;
     44         return;
     45     }
     46     if(tree[k].val<x){
     47         insert(tree[k].r,x);
     48         if(tree[tree[k].r].fix<tree[k].fix)
     49         left_turn(k); 
     50     }
     51     if(tree[k].val>x){
     52         insert(tree[k].l, x);
     53         if(tree[tree[k].l].fix<tree[k].fix)
     54         right_turn(k);
     55     }
     56 } 
     57 void del(int &k,int x){
     58    if(tree[k].val==x){
     59      if(tree[k].weight>1){
     60        tree[k].weight--;
     61        tree[k].size--;
     62        return;
     63      } 
     64      if(tree[k].l*tree[k].r==0)
     65         k=tree[k].l+tree[k].r;
     66      else  
     67        if(tree[tree[k].l].fix<tree[tree[k].r].fix)
     68          right_turn(k),del(k,x);
     69        else 
     70          left_turn(k),del(k,x); 
     71    }
     72    else
     73      if(tree[k].val>x)
     74      tree[k].size--,del(tree[k].l,x);
     75      else 
     76      tree[k].size--,del(tree[k].r,x);
     77 }
     78 int find1(int &k,int x){
     79      if(k==0) return 0;
     80      if(tree[k].val==x) return tree[tree[k].l].size+1;
     81      if(tree[k].val<x) return tree[tree[k].l].size+tree[k].weight+find1(tree[k].r,x);
     82      if(tree[k].val>x) return find1(tree[k].l,x);
     83 }
     84 int find2(int &k,int x){
     85     if(x<=tree[tree[k].l].size) 
     86     return find2(tree[k].l,x);
     87     if(x>tree[tree[k].l].size+tree[k].weight)
     88     return find2(tree[k].r,x-tree[tree[k].l].size-tree[k].weight);
     89     return tree[k].val;
     90 }
     91 void min_max(int &k,int x){
     92      if(k==0) return;
     93      if(tree[k].val<x)
     94      ans=k,min_max(tree[k].r,x);
     95      else min_max(tree[k].l,x);
     96 } 
     97 void max_min(int &k,int x){
     98      if(k==0) return;
     99      if(tree[k].val>x)
    100      ans=k,max_min(tree[k].l,x);
    101      else max_min(tree[k].r,x);
    102 } 
    103 int main(){
    104     int f,x;
    105     scanf("%d",&m);
    106     for (int i=1;i<=m;++i){
    107         scanf("%d%d",&f,&x);
    108         ans=0;
    109         if (f==1) insert(root,x);
    110         if (f==2) del(root,x);
    111         if (f==3) printf("%d
    ",find1(root,x));
    112         if (f==4) printf("%d
    ",find2(root,x));
    113         if (f==5) {min_max(root,x); printf("%d
    ",tree[ans].val);}
    114         if (f==6) {max_min(root,x); printf("%d
    ",tree[ans].val);}
    115     }
    116     return 0;
    117 }
    
    
    
     
  • 相关阅读:
    吴裕雄 19-Mysql 连接的使用
    吴裕雄 18-MySQL GROUP BY 语句
    吴裕雄 17-MySQL 排序
    吴裕雄 16-MySQL UNION 操作符
    吴裕雄 15-MySQL LIKE 子句
    吴裕雄 14-MySQL DELETE 语句
    吴裕雄 13-MySQL UPDATE 查询
    【2017中国大学生程序设计竞赛
    【2017中国大学生程序设计竞赛
    【AtCoder Regular Contest 082 F】Sandglass
  • 原文地址:https://www.cnblogs.com/kanchuang/p/11259975.html
Copyright © 2011-2022 走看看