treap启发式合并
2015-04-05 11:19
344 查看
注意输入v要在建根的前面。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <ctime> #include <queue> using namespace std; const int maxn = 100000 + 10; int tot = 0, f[maxn], n, Q, v[maxn]; char cmd; struct Node{ int r, v, s; Node* ch[2]; void maintain(){ s = ch[0] -> s + ch[1] -> s + 1; return ; } }*null = new Node(), *root[maxn], nodes[maxn]; queue<Node*> RAM; Node* node(){ Node* o; if(!RAM.empty()) o = RAM.front(), RAM.pop(); else o = &nodes[tot ++]; return o; } void del(Node* &o){ RAM.push(o); o = null; return ; } void init(Node* &o, int v){ o -> ch[0] = o -> ch[1] = null; o -> s = 1; o -> r = rand(); o -> v = v; return ; } void rotate(Node* &o, int d){ Node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o; o -> maintain(); k -> maintain(); o = k; return ; } void insert(Node* &o, int v){ if(o == null) o = node(), init(o, v); else{ int d = v > o -> v; insert(o -> ch[d], v); if(o -> ch[d] -> r > o -> r) rotate(o, d ^ 1); else o -> maintain(); } return ; } void remove(Node* &o, int v){ if(v == o -> v){ if(o -> ch[0] != null && o -> ch[1] != null){ int d = o -> ch[0] -> r > o -> ch[1] -> r; rotate(o, d); remove(o -> ch[d], v); } else{ Node* k = o; if(o -> ch[0] != null) o = o -> ch[0]; else o = o -> ch[1]; del(k); } } else remove(o -> ch[v > o -> v], v); if(o != null) o -> maintain(); return ; } void print(Node* &o){ if(o == null) return ; print(o -> ch[0]); printf("%d ", o -> v); print(o -> ch[1]); return ; } int kth(Node* &o, int k){ if(o -> s < k || k < 1) return -1; if(o -> ch[0] -> s + 1 == k) return o -> v; if(o -> ch[0] -> s >= k) return kth(o -> ch[0], k); return kth(o -> ch[1], k - o -> ch[0] -> s - 1); } void merge(Node* &left, Node* &right){ if(left == null) return ; merge(left -> ch[0], right); merge(left -> ch[1], right); insert(right, left -> v); del(left); return ; } int findset(int x){ return x == f[x] ? x : f[x] = findset(f[x]); } void merge(int a, int b){ a = findset(a); b = findset(b); if(a == b) return ; if(root[a] -> s > root[b] -> s) swap(a, b); merge(root[a], root[b]); f[a] = b; return ; } void read(int &x){ x = 0; int sig = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); } while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar(); x *= sig; return ; } void init(){ srand(time(0)); null -> s = 0; read(n); read(Q); for(int i = 1; i <= n; i ++) read(v[i]); for(int i = 1; i <= n; i ++) f[i] = i, root[i] = node(), init(root[i], v[i]); return ; } void work(){ return ; } void print(){ return ; } int main(){ init(); work(); print(); return 0; }
相关文章推荐
- BOZJ2733 [HNOI2012]永无乡(Treap+启发式合并)
- BZOJ 2733([HNOI2012]永无乡-Treap启发式合并)
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
- 【bzoj2733】【HNOI2012】【永无乡】【treap+启发式合并】
- 【楼天城男人八题】【树分治|Treap+启发式合并】POJ1741 Tree
- 【BZOJ 2733】【HNOI 2012】永无乡【treap启发式合并】
- 3545: [ONTAK2010]Peaks 启发式合并treap 离线处理
- treap启发式合并(BZOJ2809)||splay||左偏树
- Poj 1741——treap的启发式合并
- BZOJ 2809 APIO2012 dispatching Treap+启发式合并 / 可并堆
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
- USACO 2013open :yinyang(treap+启发式合并)
- 关于treap启发式合并的一点脑洞(以bzoj2809为例)
- 【bzoj2733】[HNOI2012]永无乡 Treap启发式合并
- 【BZOJ 2733】[HNOI2012]永无乡 启发式合并treap
- 2809: [Apio2012]dispatching 启发式合并treap 可并堆
- BZOJ 2733 HNOI2012 永无乡 Treap+启发式合并
- BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
- CSU 1811 Tree Intersection(Treap启发式合并)
- 【BZOJ3510】首都 LCT维护子树信息+启发式合并