# bzoj2733: [HNOI2012]永无乡 启发式合并

## 2733: [HNOI2012]永无乡

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4059  Solved: 2167
[Submit][Status][Discuss]

5 1
4 3 2 5 1
1 2
7
Q 3 2
Q 2 1
B 2 3
B 1 5
Q 2 1
Q 2 4
Q 2 3

## Sample Output

-1
2
5
1
2

启发式合并。
  1 /**************************************************************
2     Problem: 2733
3     User: weeping
4     Language: C++
5     Result: Accepted
6     Time:4908 ms
7     Memory:4436 kb
8 ****************************************************************/
9
10 #include <bits/stdc++.h>
11
12 using namespace std;
13
14 #define lc ch[x][0]
15 #define rc ch[x][1]
16
17 int n,m,q,f[100005];
18
19 int fd(int x)
20 {
21     return f[x]==x?x:f[x]=fd(f[x]);
22 }
23
24 struct SplayTree
25 {
26
27     const static int maxn = 1e5 + 15;
28
29     int tot,root,ch[maxn][2], key[maxn], val[maxn], sz[maxn], rev[maxn], fa[maxn];
30
31     inline void init( int x, int ky, int v = 0, int par = 0 )
32     {
33         lc=rc=0, fa[x]= par, key[x] = ky, val[x] = v, sz[x] = 1, rev[x] = 0;
34     }
35
36     inline void init()
37     {
38         init( 0, 0, 0 );
39         sz[0] = 0;
40         tot = root = 0 ;
41     }
42
43     inline void push_up(int x)
44     {
45         sz[x] = sz[lc] + sz[rc] + 1;
46     }
47
48     inline void reverse(int x)
49     {
50         rev[x] ^= 1, swap( lc, rc);
51     }
52
53     inline void push_down(int x)
54     {
55         if(rev[x])
56         {
57             if(lc)  reverse(lc);
58             if(rc)  reverse(rc);
59             rev[x] = 0;
60         }
61     }
62
63     void rotate( int x)
64     {
65         int f = fa[x], gf = fa[f];
66         int t1 = (ch[f][1] == x), t2 = (ch[gf][1] == f);
67         if( gf ) ch[gf][t2] = x;
68         fa[x] = gf, ch[f][t1] = ch[x][1^t1], fa[ch[f][t1]] = f;
69         ch[x][t1^1] = f, fa[f] = x;
70         push_up( f ), push_up( x );
71     }
72
73     void splay( int x, int tar )
74     {
75         for(int f = fa[x], gf = fa[f]; f != tar; rotate(x), f = fa[x], gf = fa[f])
76         if(gf != tar)
77             rotate( ((ch[f][1] == x) == (ch[gf][1] == f) )? f: x);
78         if( !tar ) root = x;
79     }
80
81     void insert( int ky, int v)
82     {
83         int x = root, ls = root;
84         while(x)
85         {
86             push_down(x);
87             sz[x] ++, ls = x;
88             x = ch[x][ky > key[x]];
89         }
90         init( ++tot, ky, v, ls);
91         ch[ls][ky > key[ls]] = tot;
92         splay( tot, 0);
93     }
94
95     int find( int ky)
96     {
97         int x = root;
98         while(x)
99         {
100             push_down(x);
101             if(key[x] == ky) break;
102             x = ch[x][ky > key[x]];
103         }
104         if(x)   splay(x,0);
105         else x = -1;
106         return x;
107     }
108
109     // Delete Root
110     void Delete()
111     {
112         if( !ch[root][0] )
113         {
114             fa[ ch[root][1] ] = 0 ;
115             root = ch[root][1];
116         }
117         else
118         {
119             int cur = ch[root][0];
120             while( ch[cur][1] ) cur = ch[cur][1];
121             splay( cur, root );
122             ch[cur][1] = ch[root][1];
123             root = cur, fa[cur] = 0, fa[ch[root][1]] = root;
124             push_up( root );
125         }
126     }
127
128     int kth( int k)
129     {
130         int x = root;
131         if(sz[x] < k) return -1;
132         while(x)
133         {
134             push_down(x);
135             if(k == sz[lc] + 1) break;
136             if(k > sz[lc])
137                 k -= sz[lc] + 1, x = rc;
138             else
139                 x = lc;
140         }
141         if(x)   splay(x,0);
142         else x = -1;
143         return x;
144     }
145
146     int pred( void)
147     {
148         int x = root;
149         if(!x || !lc)   return -1;
150         x = lc;
151         while(rc)    push_down(x), x = rc;
152         splay( x, 0);
153         return x;
154     }
155
156     int succ( void)
157     {
158         int x = root;
159         if(!x || !rc) return -1;
160         x = rc;
161         while(lc)   push_down(x), x = lc;
162         splay( x, 0);
163         return x;
164     }
165
166     void debug( int x )
167     {
168         if( !x ) return;
169         if(lc) debug( lc );
170         printf("%d ", key[x] );
171         if(rc) debug( rc );
172     }
173
174     void qinsert(int y)
175     {
176         int x = root, ls = root, ky = key[y];
177         while(x)
178             ls = x, x = ch[x][ky > key[x]];
179         x = ls;
180         ch[x][ky > key[x]] = y,fa[y] = x, sz[y] = 1;
181         splay(y, 0);
182     }
183
184     void qmerge(int x)
185     {
186         if(!x) return;
187         int tl = lc, tr = rc;
188         lc  = rc = 0;
189         qmerge(tl);
190         qinsert(x);
191         qmerge(tr);
192     }
193     void merge(int u,int v)
194     {
195         if(u == v) return ;
196         if(sz[u]>sz[v]) swap(u,v);
197         f[u] = v, splay( v, 0);
198         qmerge(u);
199     }
200 } sp;
201
202
203 int main(void)
204 {
205     scanf("%d%d",&n,&m);
206     for(int i=1,x;i<=n;i++)
207         scanf("%d",&x),f[i]=i,sp.key[i]=x,sp.sz[i]=1;
208     for(int i=1,u,v;i<=m;i++)
209         scanf("%d%d",&u,&v),sp.merge(fd(u),fd(v));
210     scanf("%d",&q);
211     char op[5];
212     for(int i=1,x,y;i<=q;i++)
213     {
214         scanf("%s%d%d",op,&x,&y);
215         if(op[0]=='B')
216             sp.merge(fd(x),fd(y));
217         else
218             sp.splay(x,0),printf("%d\n",sp.kth(y));
219     }
220     return 0;
221 }
posted @ 2017-10-13 18:08  weeping  阅读(150)  评论(0编辑  收藏  举报