首页 > 代码库 > [BZOJ 3551] Peaks 半可持久化并查集 可持久化线段树合并
[BZOJ 3551] Peaks 半可持久化并查集 可持久化线段树合并
实现
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <algorithm> 6 #include <map> 7 using namespace std; 8 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 9 inline int rd(void) { 10 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; 11 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; 12 } 13 14 const int N = 100005; 15 const int M = 500005; 16 const int S = 5000000; 17 const int INF = ~0u>>2; 18 19 int n, m, q, h[N]; 20 int Hash[N], idx; 21 void Descrete(void) { 22 F(i, 1, n) Hash[++idx] = h[i]; 23 sort(Hash+1, Hash+idx+1); 24 idx = unique(Hash+1, Hash+idx+1) - Hash - 1; 25 F(i, 1, n) h[i] = lower_bound(Hash+1, Hash+idx+1, h[i]) - Hash; 26 } 27 28 struct E { 29 int u, v, d; 30 friend inline bool operator < (E A, E B) { return A.d < B.d; } 31 }e[M]; 32 33 int f[N], s[N], w[N]; 34 inline int Find(int x, int d = INF) { 35 while (x != f[x] && d >= w[x]) 36 x = f[x]; 37 return x; 38 } 39 40 int tot, Froot[N]; map<int, int> root[N]; 41 int c[S][2], cnt[S]; 42 43 inline void Insert(int &x, int L, int R, int w) { 44 cnt[x = ++tot] = 1; 45 if (L == R) return; 46 int M = (L+R)>>1; 47 w <= M ? Insert(c[x][0], L, M, w) : Insert(c[x][1], M+1, R, w); 48 } 49 inline int Merge(int x, int y) { 50 if (!x || !y) return x+y; 51 int z = ++tot; cnt[z] = cnt[x] + cnt[y]; 52 c[z][0] = Merge(c[x][0], c[y][0]); 53 c[z][1] = Merge(c[x][1], c[y][1]); 54 return z; 55 } 56 inline int Query(int x, int L, int R, int K) { 57 if (L == R) return L; 58 int M = (L+R)>>1; 59 return K <= cnt[c[x][1]] ? Query(c[x][1], M+1, R, K) : Query(c[x][0], L, M, K - cnt[c[x][1]]); 60 } 61 62 int main(void) { 63 #ifndef ONLINE_JUDGE 64 freopen("xsy1661.in", "r", stdin); 65 #endif 66 67 n = rd(), m = rd(), q = rd(); 68 F(i, 1, n) h[i] = rd(); 69 Descrete(); 70 71 F(i, 1, m) { 72 int u = rd(), v = rd(), d = rd(); 73 e[i] = (E){ u, v, d }; 74 } 75 sort(e+1, e+m+1); 76 77 F(i, 1, n) f[i] = i, s[i] = 0, w[i] = INF; 78 F(i, 1, n) { 79 Insert(Froot[i], 1, idx, h[i]); 80 root[i][-INF] = Froot[i]; 81 } 82 83 for (int i = 1, T = 1; i <= m && T <= n; i++) { 84 int u = e[i].u, v = e[i].v, d = e[i].d; 85 int fu = Find(u), fv = Find(v); 86 if (fu == fv) continue; T++; 87 if (s[fu] > s[fv]) swap(fu, fv); 88 f[fu] = fv, s[fv] += (s[fv] == s[fu]), w[fu] = d; 89 root[fv][d] = Froot[fv] = Merge(Froot[fv], Froot[fu]); 90 } 91 92 F(i, 1, q) { 93 int x = rd(), d = rd(), K = rd(); 94 int t = Find(x, d); 95 map<int, int>::iterator it = root[t].upper_bound(d); 96 int rt = (--it) -> second; 97 if (K < 1 || K > cnt[rt]) 98 puts("-1"); 99 else printf("%d\n", Hash[Query(rt, 1, idx, K)]); 100 } 101 102 return 0; 103 }
[BZOJ 3551] Peaks 半可持久化并查集 可持久化线段树合并
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。