zoukankan      html  css  js  c++  java
  • poj 1442 Black Box

    http://poj.org/problem?id=1442

      简单BST求k大数,在线插入各个元素并查询。

    SBT版:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <queue>
      7 
      8 using namespace std;
      9 typedef vector<int> vi;
     10 
     11 struct SBTNode{
     12     SBTNode *left, *right;
     13     int key, size;
     14     SBTNode(int k){
     15         key = k;
     16         size = 1;
     17         left = right = NULL;
     18     }
     19 };
     20 
     21 struct SBT{
     22     SBTNode *root;
     23 
     24     SBT(){
     25         root = NULL;
     26     }
     27 
     28     void rightRotate(SBTNode *&x){
     29         SBTNode *y = x->left;
     30 
     31         x->left = y->right;
     32         y->right = x;
     33         y->size = x->size;
     34 
     35         int ls = x->left ? x->left->size : 0;
     36         int rs = x->right ? x->right->size : 0;
     37 
     38         x->size = ls + rs + 1;
     39         x = y;
     40     }
     41 
     42     void leftRotate(SBTNode *&x){
     43         SBTNode *y = x->right;
     44 
     45         x->right = y->left;
     46         y->left = x;
     47         y->size = x->size;
     48 
     49         int ls = x->left ? x->left->size : 0;
     50         int rs = x->right ? x->right->size : 0;
     51 
     52         x->size = ls + rs + 1;
     53         x = y;
     54     }
     55 
     56     void maintain(SBTNode *&T, bool rightDeeper){
     57         if (!T) return ;
     58         if (!rightDeeper){
     59             if (T->left == NULL) return ;
     60 
     61             int rs = T->right ? T->right->size : 0;
     62 
     63             if (T->left->left && T->left->left->size > rs){
     64                 rightRotate(T);
     65             }
     66             else if (T->left->right && T->left->right->size > rs){
     67                 leftRotate(T->left);
     68                 rightRotate(T);
     69             }
     70             else return ;
     71         }
     72         else {
     73             if (T->right == NULL) return ;
     74 
     75             int ls = T->left ? T->left->size : 0;
     76 
     77             if (T->right->right && T->right->right->size > ls){
     78                 leftRotate(T);
     79             }
     80             else if (T->right->left && T->right->left->size > ls){
     81                 rightRotate(T->right);
     82                 leftRotate(T);
     83             }
     84             else return ;
     85         }
     86         maintain(T->left, false);
     87         maintain(T->right, true);
     88         maintain(T, false);
     89         maintain(T, true);
     90     }
     91 
     92     void ins(SBTNode *&T, SBTNode *x){
     93         if (!T){
     94             T = x;
     95             return ;
     96         }
     97         T->size++;
     98         if (x->key < T->key){
     99             ins(T->left, x);
    100         }
    101         else{
    102             ins(T->right, x);
    103         }
    104         maintain(T, x->key >= T->key);
    105     }
    106 
    107     void del(SBTNode *&T, int key){
    108         if (!T) return ;
    109         T->size--;
    110         if (key < T->key) del(T->left, key);
    111         else if (key > T->key) del(T->right, key);
    112         else{
    113             SBTNode *t;
    114 
    115             if (!T->left && !T->right){
    116                 delete T;
    117                 T = NULL;
    118             }
    119             else if (!T->right){
    120                 t = T;
    121                 T = T->left;
    122                 delete t;
    123             }
    124             else if (!T->left){
    125                 t = T;
    126                 T = T->right;
    127                 delete t;
    128             }
    129             else{
    130                 t = T->right;
    131                 while (t->left) t = t->left;
    132                 T->key = t->key;
    133                 del(T->right, t->key);
    134             }
    135         }
    136     }
    137 
    138     int find(SBTNode *T, int k){ // find the kth min
    139         SBTNode *p = T;
    140 
    141         if (k <= 0) return 0;
    142         if (k > p->size) return -1;
    143 
    144         while (true){
    145             int ls = p->left ? p->left->size : 0;
    146 
    147 //printf("k %d  p %d\n", k, p);
    148             if (k == ls + 1) return p->key;
    149             if (k <= ls) p = p->left;
    150             else k -= ls + 1, p = p->right;
    151         }
    152     }
    153 
    154     void print(SBTNode *T){
    155         if (!T) return ;
    156         printf("cur %d : key %d left %d right %d size %d\n", T, T->key, T->left, T->right, T->size);
    157         print(T->left);
    158         print(T->right);
    159     }
    160 
    161     void delAll(SBTNode *T){
    162         if (T->left) delAll(T->left);
    163         if (T->right) delAll(T->right);
    164         delete T;
    165     }
    166 }T;
    167 
    168 queue<int> op, blackBox;
    169 
    170 void deal(){
    171     T.root = NULL;
    172     SBTNode *tmp;
    173 
    174     int cur = 1, cnt = 0;
    175 
    176     while (blackBox.size() && op.size()){
    177         int a = blackBox.front();
    178 
    179         tmp = new SBTNode(a);
    180         blackBox.pop();
    181         T.ins(T.root, tmp);
    182         cnt++;
    183         while (op.size() && op.front() == cnt){
    184 //T.print(T.root);
    185             printf("%d\n", T.find(T.root, cur));
    186             cur++;
    187             op.pop();
    188         }
    189     }
    190     T.delAll(T.root);
    191 }
    192 
    193 int main(){
    194     int n, m;
    195 
    196     while (~scanf("%d%d", &n, &m)){
    197         while (blackBox.size()) blackBox.pop();
    198         while (op.size()) op.pop();
    199 
    200         while (n--){
    201             int a;
    202 
    203             scanf("%d", &a);
    204             blackBox.push(a);
    205         }
    206         while (m--){
    207             int a;
    208 
    209             scanf("%d", &a);
    210             op.push(a);
    211         }
    212         deal();
    213     }
    214 
    215     return 0;
    216 }

    Treap版:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cassert>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <queue>
      8 #include <ctime>
      9 
     10 using namespace std;
     11 
     12 struct Node{
     13     Node *child[2];
     14     int key;
     15     int fix;
     16     int size;
     17     Node(int k){
     18         key = k;
     19         fix = rand();
     20         size = 1;
     21         child[0] = child[1] = NULL;
     22     }
     23 };
     24 
     25 struct Treap{
     26     Node *root;
     27     int size;
     28     Treap(){
     29         srand(time(NULL));
     30         root = NULL;
     31         size = 0;
     32     }
     33 };
     34 
     35 void rotateTreap(Node *&rt, bool left){
     36     bool right = !left;
     37     Node *p = rt->child[right];
     38 
     39     rt->child[right] = p->child[left];
     40     p->child[left] = rt;
     41     p->size = rt->size;
     42 
     43     int ls = rt->child[left] ? rt->child[left]->size : 0;
     44     int rs = rt->child[right] ? rt->child[right]->size : 0;
     45 
     46     rt->size = ls + rs + 1;
     47     rt = p;
     48 }
     49 
     50 void insertTreap(Node *&rt, Node *x){
     51     if (!rt){
     52         rt = x;
     53 
     54         return ;
     55     }
     56 
     57     rt->size++;
     58     if (x->key < rt->key){
     59         insertTreap(rt->child[true], x);
     60         if (rt->child[true]->fix > rt->fix){
     61             rotateTreap(rt, false);
     62         }
     63     }
     64     else{
     65         insertTreap(rt->child[false], x);
     66         if (rt->child[false]->fix > rt->fix){
     67             rotateTreap(rt, true);
     68         }
     69     }
     70 }
     71 
     72 void deleteAllTreap(Node *rt){
     73     if (!rt) return ;
     74     deleteAllTreap(rt->child[true]);
     75     deleteAllTreap(rt->child[false]);
     76     delete rt;
     77 }
     78 
     79 int findTreap(Node *rt, int pos){
     80     if (!rt || rt->size < pos) return -1;
     81 
     82     Node *p = rt;
     83 
     84     while (true){
     85 //printf("pos %d\n", pos);
     86         int ln = p->child[true] ? p->child[true]->size : 0;
     87 
     88         if (ln + 1 == pos) return p->key;
     89         else if (ln >= pos) p = p->child[true];
     90         else pos -= ln + 1, p = p->child[false];
     91     }
     92 }
     93 
     94 void print(Node *rt){
     95     if (!rt) return ;
     96     printf("%d key %d fix %d left %d right %d size %d\n", rt, rt->key, rt->fix, rt->child[true], rt->child[false], rt->size);
     97     print(rt->child[true]);
     98     print(rt->child[false]);
     99 }
    100 
    101 queue<int> blackBox, op;
    102 
    103 void deal(){
    104     Treap T = Treap();
    105 
    106     int cur = 1;
    107 
    108     while (blackBox.size() && op.size()){
    109         int t = blackBox.front();
    110         blackBox.pop();
    111 
    112         Node *tmp = new Node(t);
    113 
    114         insertTreap(T.root, tmp);
    115 //print(T.root);
    116 //printf("insert %d\n", tmp);
    117         T.size++;
    118 
    119         while (op.size() && T.size == op.front()){
    120             printf("%d\n", findTreap(T.root, cur));
    121             op.pop();
    122             cur++;
    123         }
    124     }
    125     deleteAllTreap(T.root);
    126 }
    127 
    128 int main(){
    129     int n, m;
    130 
    131     while (~scanf("%d%d", &n, &m)){
    132         int a;
    133 
    134         while (blackBox.size()) blackBox.pop();
    135         while (op.size()) op.pop();
    136 
    137         while (n--){
    138             scanf("%d", &a);
    139             blackBox.push(a);
    140         }
    141         while (m--){
    142             scanf("%d", &a);
    143             op.push(a);
    144         }
    145         deal();
    146     }
    147 
    148     return 0;
    149 }

       这题还可以用线段树或者树状数组离线离散化处理! 

    ——written by Lyon

  • 相关阅读:
    Knime 使用 初探
    MySql可视化工具MySQL Workbench使用教程
    MySQL导入sql 文件的5大步骤
    Import MySQL Dumpfile, SQL Datafile Into My Database
    导入已有的vmdk文件,发现网络无法连通
    VirtualBox镜像复制载入
    对自己说的话
    linux遇见的问题
    vbox下安装 linux 64 bit出现“kernel requires an x86_64 cpu
    Servlet 3 HttpServletRequest HttpServletResponse 验证码图片 form表单
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1442_Lyon.html
Copyright © 2011-2022 走看看