离线做法:将所有的边和询问按照边权从小到大排序,遇到边就合并两个端点所在的线段树,遇到询问就查询该点所在的权值线段树中第 大的值。
一开始写线段树合并没有开并查集(雾
而且空间还开小了,胡乱调了半天,线段树合并的空间复杂度应该是
的
#include <cstdio>
#include <algorithm>
const int N = 2000005, M = 100005;
struct Node {
int a, b, c, d; bool f;
bool operator < (const Node &cmp) const {
if (c == cmp.c) return f == 0;
return c < cmp.c;
}
} a[1000005];
struct Hill {
int h, id;
bool operator < (const Hill &cmp) const {
return h < cmp.h;
}
} h[M];
int n, m, q, sum[N], lson[N], rson[N], root[M], fa[M], cnt, ans[500005];
int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x * f;
}
int find(int x) {
if (x != fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
void insert(int &cur, int l, int r, int p) {
if (!cur) cur = ++cnt;
++sum[cur];
if (l == r) return;
int mid = l + (r - l >> 1);
if (p <= mid) insert(lson[cur], l, mid, p);
else insert(rson[cur], mid + 1, r, p);
}
int merge(int x, int y) {
if (!x) return y;
if (!y) return x;
sum[x] += sum[y];
lson[x] = merge(lson[x], lson[y]);
rson[x] = merge(rson[x], rson[y]);
return x;
}
int query(int cur, int l, int r, int k) {
if (l == r) return l;
int mid = l + (r - l >> 1);
if (sum[lson[cur]] >= k) return query(lson[cur], l, mid, k);
return query(rson[cur], mid + 1, r, k - sum[lson[cur]]);
}
int main() {
n = read(), m = read(), q = read();
for (int i = 1; i <= n; ++i) h[i].h = read(), h[i].id = i;
std::sort(h + 1, h + n + 1);
for (int i = 1; i <= n; ++i) insert(root[h[i].id], 1, n, i), fa[i] = i;
for (int i = 1; i <= m; ++i)
a[i].a = read(), a[i].b = read(), a[i].c = read(), a[i].f = 0;
for (int i = m + 1; i <= m + q; ++i)
a[i].a = read(), a[i].c = read(), a[i].b = read(), a[i].f = 1, a[i].d = i - m;
std::sort(a + 1, a + m + q + 1);
for (int i = 1; i <= m + q; ++i) {
if (a[i].f == 0) {
int fx = find(a[i].a), fy = find(a[i].b);
if (fx == fy) continue;
root[fy] = merge(root[fx], root[fy]), fa[fy] = fx;
} else {
int fx = find(a[i].a);
if (a[i].b > sum[root[fx]]) ans[a[i].d] = -1;
else ans[a[i].d] = query(root[fx], 1, n, sum[root[fx]] - a[i].b + 1);
}
}
for (int i = 1; i <= q; ++i) {
if (ans[i] == -1) puts("-1");
else printf("%d\n", h[ans[i]].h);
}
return 0;
}