Kruskal重构树。
引用PoPoQQQ的一张图:
只要建出树,每次从点 向上倍增到最高的权值小于等于 的点 ,然后查询主席树 中第 大的值即可。
(交上去一直显示
,然后就使劲卡常啊卡常啊,但发现其实是
了 QAQ 辣鸡bzoj
(显然是我内存算大了,而且还大了不少,虽然是
次合并,但最多只会新添
个节点!!!
(而且主席树的节点个数最多是
个:第一个
是一开始的最底层的
个节点,每个节点都会生成一条链;第二个
是二叉树上前
层的
个节点,每个节点也会带着一条链
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N = 100005, M = 500005, X = 3400005;
int fa[N<<1], faa[N<<1], val[N], f[N<<1][18], root[N<<1], sum[X], lson[X], rson[X], cnt, node, n;
struct Hight {
int h, id;
bool operator < (const Hight &cmp) const {
return h < cmp.h;
}
} a[N];
struct Edge {
int u, v, c;
bool operator < (const Edge &cmp) const {
return c < cmp.c;
}
} e[M];
int read() {
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x;
}
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);
}
void merge(int &cur, int x, int y, int l, int r) {
if (!cur) cur = ++cnt;
sum[cur] = sum[x] + sum[y];
if (l == r) return;
int mid = l + (r - l >> 1);
if (lson[x] && lson[y]) merge(lson[cur], lson[x], lson[y], l, mid);
else if (lson[x]) lson[cur] = lson[x];
else if (lson[y]) lson[cur] = lson[y];
if (rson[x] && rson[y]) merge(rson[cur], rson[x], rson[y], mid + 1, r);
else if (rson[x]) rson[cur] = rson[x];
else if (rson[y]) rson[cur] = rson[y];
}
int jump(int v, int x) {
for (int i = 17; i >= 0; --i)
if (f[v][i] && val[f[v][i]-n] <= x) v = f[v][i];
return v;
}
int query(int cur, int l, int r, int k) {
if (l == r) return a[l].h;
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(); int m = read(), q = read();
for (int i = 1; i <= n; ++i) a[i].h = read(), a[i].id = i;
std::sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i) insert(root[a[i].id], 1, n, i), fa[i] = i;
for (int i = 1; i <= m; ++i)
e[i].u = read(), e[i].v = read(), e[i].c = read();
std::sort(e + 1, e + m + 1);
node = n;
for (int i = 1; i <= m; ++i) {
int fx = find(e[i].u), fy = find(e[i].v);
if (fx == fy) continue;
fa[++node] = fa[fx] = fa[fy] = faa[fx] = faa[fy] = node;
val[node-n] = e[i].c;
merge(root[node], root[fx], root[fy], 1, n);
}
for (int i = 1; i <= node; ++i) f[i][0] = faa[i];
for (int j = 1; j <= 17; ++j)
for (int i = 1; i <= node; ++i)
f[i][j] = f[f[i][j-1]][j-1];
int lastans = 0;
while (q--) {
int v = read(), x = read(), k = read();
if (lastans != -1) v ^= lastans, x ^= lastans, k ^= lastans;
int u = jump(v, x);
if (sum[root[u]] < k) lastans = -1;
else lastans = query(root[u], 1, n, sum[root[u]] - k + 1);
printf("%d\n", lastans);
}
return 0;
}