treap启发式合并

注意输入v要在建根的前面。

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <queue>
  8 using namespace std;
  9 const int maxn = 100000 + 10;
 10 int tot = 0, f[maxn], n, Q, v[maxn];
 11 char cmd;
 12 struct Node{
 13     int r, v, s;
 14     Node* ch[2];
 15     void maintain(){
 16         s = ch[0] -> s + ch[1] -> s + 1;
 17         return ;
 18     }
 19 }*null = new Node(), *root[maxn], nodes[maxn];
 20 queue<Node*> RAM;
 21 Node* node(){
 22     Node* o;
 23     if(!RAM.empty()) o = RAM.front(), RAM.pop();
 24     else o = &nodes[tot ++];
 25     return o;
 26 }
 27 void del(Node* &o){
 28     RAM.push(o);
 29     o = null;
 30     return ;
 31 }
 32 void init(Node* &o, int v){
 33     o -> ch[0] = o -> ch[1] = null;
 34     o -> s = 1;
 35     o -> r = rand();
 36     o -> v = v;
 37     return ;
 38 }
 39 void rotate(Node* &o, int d){
 40     Node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o;
 41     o -> maintain(); k -> maintain(); o = k; return ;
 42 }
 43 void insert(Node* &o, int v){
 44     if(o == null) o = node(), init(o, v);
 45     else{
 46         int d = v > o -> v;
 47         insert(o -> ch[d], v);
 48         if(o -> ch[d] -> r > o -> r) rotate(o, d ^ 1);
 49         else o -> maintain();
 50     }
 51     return ;
 52 }
 53 void remove(Node* &o, int v){
 54     if(v == o -> v){
 55         if(o -> ch[0] != null && o -> ch[1] != null){
 56             int d = o -> ch[0] -> r > o -> ch[1] -> r;
 57             rotate(o, d); remove(o -> ch[d], v);
 58         }
 59         else{
 60             Node* k = o;
 61             if(o -> ch[0] != null) o = o -> ch[0];
 62             else o = o -> ch[1];
 63             del(k);
 64         }
 65     }
 66     else remove(o -> ch[v > o -> v], v);
 67     if(o != null) o -> maintain();
 68     return ;
 69 }
 70 void print(Node* &o){
 71     if(o == null) return ;
 72     print(o -> ch[0]);
 73     printf("%d ", o -> v);
 74     print(o -> ch[1]);
 75     return ;
 76 }
 77 int kth(Node* &o, int k){
 78     if(o -> s < k || k < 1) return -1;
 79     if(o -> ch[0] -> s + 1 == k) return o -> v;
 80     if(o -> ch[0] -> s >= k) return kth(o -> ch[0], k);
 81     return kth(o -> ch[1], k - o -> ch[0] -> s - 1);
 82 }
 83 void merge(Node* &left, Node* &right){
 84     if(left == null) return ;
 85     merge(left -> ch[0], right);
 86     merge(left -> ch[1], right);
 87     insert(right, left -> v);
 88     del(left); return ;
 89 }
 90 int findset(int x){
 91     return x == f[x] ? x : f[x] = findset(f[x]);
 92 }
 93 void merge(int a, int b){
 94     a = findset(a); b = findset(b);
 95     if(a == b) return ;
 96     if(root[a] -> s > root[b] -> s) swap(a, b);
 97     merge(root[a], root[b]);
 98     f[a] = b; return ;
 99 }
100 void read(int &x){
101     x = 0; int sig = 1; char ch = getchar();
102     while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); }
103     while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
104     x *= sig; return ;
105 }
106 void init(){
107     srand(time(0));
108     null -> s = 0;
109     read(n); read(Q);
110     for(int i = 1; i <= n; i ++) read(v[i]);
111     for(int i = 1; i <= n; i ++) f[i] = i, root[i] = node(), init(root[i], v[i]);
112     return ;
113 }
114 void work(){
115     
116     return ;
117 }
118 void print(){
119 
120     return ;
121 }
122 int main(){
123     init();
124     work();
125     print();
126     return 0;
127 }

 

posted @ 2015-04-05 11:19  AI_Believer  阅读(317)  评论(0编辑  收藏  举报