• poj 1442 Treap实现名次树


    Treap的入门题目,每个结点多维护一个size表示以它为根的子树的结点数,然后查kth的时候一层一层向下即可。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <ctime>
     6 using namespace std;
     7 
     8 struct Node 
     9 {
    10     Node * ch[2];
    11     int r;      
    12     int v;      
    13     int s;
    14     int cmp( int x )
    15     {
    16         if ( x == v ) return -1;
    17         return x < v ? 0 : 1;
    18     }    
    19     void maintain()
    20     {
    21         s = 1;
    22         if ( ch[0] != NULL ) s += ch[0]->s;
    23         if ( ch[1] != NULL ) s += ch[1]->s;
    24     }
    25 };
    26 
    27 void rotate( Node * & o, int d )
    28 {
    29     Node * k = o->ch[d ^ 1];
    30     o->ch[d ^ 1] = k->ch[d];
    31     k->ch[d] = o;
    32     o->maintain();
    33     k->maintain();
    34     o = k;
    35 }
    36 
    37 void insert( Node * & o, int x )
    38 {
    39     if ( o == NULL )
    40     {
    41         o = new Node();
    42         o->ch[0] = o->ch[1] = NULL;
    43         o->v = x;
    44         o->r = rand();
    45         o->s = 1;
    46     }
    47     else
    48     {
    49         int d = ( x < o->v ? 0 : 1 );  
    50         insert( o->ch[d], x );
    51         if ( o->ch[d]->r > o->r )
    52         {
    53             rotate( o, d ^ 1 );
    54         }
    55         o->maintain();
    56     }
    57 }
    58 
    59 int kth( Node * o, int k )
    60 {
    61     int tmp = ( o->ch[0] == NULL ? 0 : o->ch[0]->s );
    62     if ( k == tmp + 1 ) return o->v;
    63     else if ( k < tmp + 1 ) return kth( o->ch[0], k );
    64     else return kth( o->ch[1], k - tmp - 1 );
    65 }
    66 
    67 const int N = 30001;
    68 int a[N];
    69 
    70 int main ()
    71 {
    72     int n, m;
    73     while ( scanf("%d%d", &n, &m) != EOF )
    74     {
    75         Node * root = NULL;
    76         for ( int i = 1; i <= n; i++ )
    77         {
    78             scanf("%d", a + i);
    79         }
    80         int tt, cnt = 1;
    81         for ( int i = 1; i <= m; i++ )
    82         {
    83             scanf("%d", &tt);
    84             while ( cnt <= tt )
    85             {
    86                 insert( root, a[cnt++] );
    87             }
    88             printf("%d
    ", kth( root, i ));
    89         }
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    Android开发 Android Studio2.0 教程从入门到精通Windows版
    SQLSERVER 执行过的语句查询
    通过身份证分析出生年月日、性别、年龄的SQL语句
    SQL 根据日期精确计算年龄
    SQL 语句转换格式函数Cast、Convert
    Delphi 单元
    【转】实现Ribbon风格的窗体
    Delphi的打开文件对话框-TOpenDialog
    Delphi数据类型转换
    深入理解javascript中的立即执行函数(function(){…})()
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4695242.html
Copyright © 2020-2023  润新知