直接平衡树启发式合并就好了。。。貌似是个很高端的东西。。

貌似可以证明splay的启发式合并是均摊$O(nlogn)$的。。。而其他平衡树都不行,所以其他的复杂度都是$O(nlog^2n)的$的

所以就用平板电视里的splay好啦!2333

 

 1 /**************************************************************
 2     Problem: 2733
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:2148 ms
 7     Memory:9756 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <ext/pb_ds/assoc_container.hpp>
12 #include <ext/pb_ds/tree_policy.hpp>
13  
14 using namespace std;
15 using namespace __gnu_pbds;
16 typedef tree<int, int, less<int>, splay_tree_tag, tree_order_statistics_node_update> Tree;
17 typedef Tree :: iterator iter;
18 const int N = 1e5 + 5;
19  
20 int read();
21 int get_op();
22  
23 int n, m;
24 int a[N];
25 int fa[N], sz[N];
26 Tree T[N];
27  
28 int find(int x) {
29     return x == fa[x] ? x : fa[x] = find(fa[x]);
30 }
31  
32 void _union(int x, int y) {
33     iter it;
34     x = find(x), y = find(y);
35     if (x == y) return;
36     if (sz[x] < sz[y]) swap(x, y);
37     for (it = T[y].begin(); it != T[y].end(); ++it)
38         T[x][it -> first] = it -> second;
39     fa[y] = x, sz[x] += sz[y], T[y].clear();
40 }
41  
42 int query() {
43     int x = find(read()), k = read();
44     if (k > T[x].size()) return -1;
45     return T[find(x)].find_by_order(k - 1) -> second;
46 }
47  
48 int main() {
49     int i, Q, oper;
50     n = read(), m = read();
51     for (i = 1; i <= n; ++i) {
52         a[i] = read(), fa[i] = i;
53         T[i][a[i]] = i;
54     }
55     for (i = 1; i <= m; ++i) _union(read(), read());
56     for (Q = read(); Q; --Q) {
57         oper = get_op();
58         if (oper == 0) _union(read(), read());
59         else printf("%d\n", query());
60     }
61     return 0;
62 }
63  
64 inline int read() {
65     static int x;
66     static char ch;
67     x = 0, ch = getchar();
68     while (ch < '0' || '9' < ch)
69         ch = getchar();
70     while ('0' <= ch && ch <= '9') {
71         x = x * 10 + ch - '0';
72         ch = getchar();
73     }
74     return x;
75 }
76  
77 inline int get_op() {
78     static char ch;
79     ch = getchar();
80     while (ch != 'Q' && ch != 'B') ch = getchar();
81     return ch == 'Q';
82 }
View Code

 

posted on 2015-05-25 20:46  Xs酱~  阅读(474)  评论(0编辑  收藏  举报