左偏树+并查集。左偏树就是可合并二叉堆。
1 /* 1512 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 typedef struct node_t { 43 int l, r, f, v, dis; 44 45 node_t() {} 46 47 node_t(int l_, int r_, int f_, int v_): 48 l(l_), r(r_), f(f_), v(v_) {} 49 50 } node_t; 51 52 const int maxn = 1e5+5; 53 node_t H[maxn]; 54 55 int find(int x) { 56 if (H[x].f == x) 57 return x; 58 return H[x].f = find(H[x].f); 59 } 60 61 int merge(int a, int b) { 62 if (a == 0) return b; 63 if (b == 0) return a; 64 65 if (H[a].v < H[b].v) swap(a, b); 66 H[a].r = merge(H[a].r, b); 67 H[H[a].r].f = a; 68 if (H[H[a].l].dis < H[H[a].r].dis) swap(H[a].l, H[a].r); 69 H[a].dis = H[H[a].r].dis + 1; 70 71 return a; 72 } 73 74 int pop(int a) { 75 int l = H[a].l, r = H[a].r; 76 77 H[l].f = l; 78 H[r].f = r; 79 80 H[a].l = H[a].r = H[a].dis = 0; 81 return merge(l, r); 82 } 83 84 int main() { 85 ios::sync_with_stdio(false); 86 #ifndef ONLINE_JUDGE 87 freopen("data.in", "r", stdin); 88 freopen("data.out", "w", stdout); 89 #endif 90 91 int n, m; 92 int x, y; 93 int fx, fy; 94 int ans; 95 96 H[0].dis = -1; 97 H[0].l = H[0].r = H[0].f = H[0].v = 0; 98 while (scanf("%d", &n) != EOF) { 99 rep(i, 1, n+1) { 100 scanf("%d", &H[i].v); 101 H[i].l = H[i].r = H[i].dis = 0; 102 H[i].f = i; 103 } 104 105 scanf("%d", &m); 106 while (m--) { 107 scanf("%d %d", &x, &y); 108 fx = find(x); 109 fy = find(y); 110 111 if (fx == fy) { 112 puts("-1"); 113 } else { 114 H[fx].v >>= 1; 115 x = pop(fx); 116 x = merge(x, fx); 117 118 H[fy].v >>= 1; 119 y = pop(fy); 120 y = merge(y, fy); 121 122 x = merge(x, y); 123 ans = H[x].v; 124 printf("%d\n", ans); 125 } 126 } 127 } 128 129 #ifndef ONLINE_JUDGE 130 printf("time = %d.\n", (int)clock()); 131 #endif 132 133 return 0; 134 }
然后用优先级队列+并查集试了一下居然也过了,左偏树是764ms,而优先级队列是811ms。
1 /* 1512 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int maxn = 1e5+5; 43 int pre[maxn]; 44 priority_queue<int, vi, less<int> > Q[maxn]; 45 46 int find(int x) { 47 if (x == pre[x]) 48 return x; 49 return pre[x] = find(pre[x]); 50 } 51 52 int main() { 53 ios::sync_with_stdio(false); 54 #ifndef ONLINE_JUDGE 55 freopen("data.in", "r", stdin); 56 freopen("data.out", "w", stdout); 57 #endif 58 59 int n, m; 60 int x, y, fx, fy; 61 int ma, mb; 62 int ans, tmp; 63 64 while (scanf("%d", &n)!=EOF) { 65 rep(i, 1, n+1) { 66 scanf("%d", &tmp); 67 while (!Q[i].empty()) 68 Q[i].pop(); 69 Q[i].push(tmp); 70 pre[i] = i; 71 } 72 73 scanf("%d", &m); 74 while (m--) { 75 scanf("%d %d", &x, &y); 76 fx = find(x); 77 fy = find(y); 78 79 if (fx == fy) { 80 puts("-1"); 81 } else { 82 ma = Q[fx].top(); 83 Q[fx].pop(); 84 Q[fx].push(ma>>1); 85 86 mb = Q[fy].top(); 87 Q[fy].pop(); 88 Q[fy].push(mb>>1); 89 90 if (SZ(Q[fx]) > SZ(Q[fy])) 91 swap(fx, fy); 92 93 pre[fx] = fy; 94 while (!Q[fx].empty()) { 95 Q[fy].push(Q[fx].top()); 96 Q[fx].pop(); 97 } 98 99 ans = Q[fy].top(); 100 printf("%d\n", ans); 101 } 102 } 103 } 104 105 #ifndef ONLINE_JUDGE 106 printf("time = %d.\n", (int)clock()); 107 #endif 108 109 return 0; 110 }