POJ--1442(Treap)
2015-03-16 23:19:15
思路:一个比较裸的求第k大,解法很多... 各种树 or 优先队列(堆)...
这里权当 treap 练练手。和POJ2985很类似。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 const int MAXN = 60010; 27 28 int N,M; 29 int A[MAXN],u[MAXN]; 30 31 struct Treap{ 32 int root,tcnt; 33 int key[MAXN],pro[MAXN],son[MAXN][2],cnt[MAXN],sz[MAXN]; 34 void clear(){ 35 root = 0; 36 tcnt = 0; 37 pro[0] = INF; 38 sz[0] = 0; 39 } 40 void update(int x){ 41 sz[x] = cnt[x] + sz[son[x][0]] + sz[son[x][1]]; 42 } 43 void rotate(int &x,int t){ 44 int y = son[x][t]; 45 son[x][t] = son[y][1 - t]; 46 son[y][1 - t] = x; 47 update(x); 48 update(y); 49 x = y; 50 } 51 void _insert(int &x,int k){ 52 if(x){ //非空树 53 if(key[x] == k) ++cnt[x]; 54 else{ 55 int t = k > key[x]; 56 _insert(son[x][t],k); 57 if(pro[son[x][t]] < pro[x]) rotate(x,t); 58 } 59 } 60 else{ //空树 61 x = ++tcnt; 62 cnt[x] = 1; 63 key[x] = k; 64 pro[x] = rand(); 65 } 66 update(x); 67 } 68 void _erase(int &x,int k){ 69 if(key[x] == k){ 70 if(cnt[x] > 1) cnt[x]--; 71 else{ 72 if(!son[x][0] && !son[x][1]){ 73 x = 0; 74 return; 75 } 76 int t = pro[son[x][0]] > pro[son[x][1]]; 77 rotate(x,t); 78 _erase(x,k); 79 } 80 } 81 else _erase(son[x][k > key[x]],k); 82 } 83 int _get_kth(int &x,int k){ 84 if(sz[son[x][0]] >= k) 85 return _get_kth(son[x][0],k); 86 k -= cnt[x] + sz[son[x][0]]; 87 if(k <= 0) return key[x]; 88 return _get_kth(son[x][1],k); 89 } 90 void insert(int k){ 91 _insert(root,k); 92 } 93 void erase(int k){ 94 _erase(root,k); 95 } 96 int get_kth(int k){ 97 return _get_kth(root,k); 98 } 99 }tp; 100 101 int main(){ 102 scanf("%d%d",&N,&M); 103 REP(i,N) scanf("%d",A + i); 104 REP(i,M) scanf("%d",u + i); 105 int p = 1; 106 REP(i,M){ 107 for(; p <= u[i]; ++p) 108 tp.insert(A[p]); 109 printf("%d\n",tp.get_kth(i)); 110 } 111 return 0; 112 }