P2713罗马游戏(左偏树)
糖衣炮弹的左偏树模板,解析见学习笔记。
1 #include<bits/stdc++.h> 2 using namespace std; 3 static inline int read() 4 { 5 char c; 6 int flag = 0; 7 while(not isdigit(c = getchar())) flag = (c == '-') ? 1 : flag; 8 int x = 0; 9 while(isdigit(c)) 10 { 11 x = (x << 3) + (x << 1) + c - '0'; 12 c = getchar(); 13 } 14 return flag ? -x : x; 15 } 16 static inline void write(int x) 17 { 18 if(x >= 10) write(x / 10); 19 putchar('0' + x % 10); 20 } 21 const int N = 1000000 + 10; 22 struct node 23 { 24 int pos,v; 25 friend bool operator < (node xx,node yy) { return xx.v == yy.v ? xx.pos < yy.pos : xx.v < yy.v; } 26 } val[N]; 27 int n,m; 28 bool inl[N]; 29 int lc[N],rc[N],dist[N],root[N]; 30 int merge(int x,int y) 31 { 32 if(not x or not y) return x + y; 33 if(val[y] < val[x]) swap(x,y); 34 rc[x] = merge(rc[x],y); 35 if(dist[lc[x]] < dist[rc[x]]) swap(lc[x],rc[x]); 36 dist[x] = dist[rc[x]] + 1; 37 return x; 38 } 39 int get_root(int x) 40 { 41 if(x == root[x]) return x; 42 else return root[x] = get_root(root[x]); 43 } 44 void del(int x) 45 { 46 inl[x] = false; 47 root[lc[x]] = root[rc[x]] = root[x] = merge(lc[x],rc[x]); 48 lc[x] = rc[x] = 0,dist[x] = -1; 49 } 50 signed int main() 51 { 52 dist[0] = -1; 53 n = read(); 54 //cout << n << endl; 55 for(int i = 1;i <= n;i++) 56 { 57 val[i].v = read(); 58 val[i].pos = i,root[i] = i,inl[i] = true; 59 } 60 m = read(); 61 while(m--) 62 { 63 char opt; 64 cin >> opt; 65 if(opt == 'M') 66 { 67 int x = read(),y = read(); 68 if(not inl[x] or not inl[y]) continue; 69 x = get_root(x),y = get_root(y); 70 if(x == y) continue; 71 root[x] = root[y] = merge(x,y); 72 } 73 else 74 { 75 int g = read(); 76 if(not inl[g]) 77 { 78 write(0),putchar('\n'); 79 continue; 80 } 81 g = get_root(g); 82 write(val[g].v),putchar('\n'); 83 del(g); 84 } 85 } 86 return 0; 87 }

浙公网安备 33010602011771号