萌新刚学OI求助
查看原帖
萌新刚学OI求助
253433
XeRnHe楼主2021/8/1 11:16

树剖+主席树,20pts其他RE

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 100005;

int n, m, len;
int a[MAXN], b[MAXN];
int nn;
int head[MAXN];
struct Edge {
	int v, next;
} edge[MAXN << 1];
int fa[MAXN], depth[MAXN], size[MAXN], son[MAXN], top[MAXN];
int tot;
int root[MAXN];
struct SegmentTree {
	int val;
	int lc, rc;
} tree[MAXN << 10];

inline long long read() {
	long long x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') {
			f = -1;
		}
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + ch - 48;
		ch = getchar();
	}
	return x * f;
}

void addEdge(int u, int v) {
	edge[++nn].v = v;
	edge[nn].next = head[u];
	head[u] = nn;
}

int clone(int p) {
	tot++;
	tree[tot] = tree[p];
	tree[tot].val++;
	return tot;
}

int update(int p, int l, int r, int q) {
	p = clone(p);
	if (l == r) {
		return p;
	}
	int mid = (l + r) >> 1;
	if (q <= mid) {
		tree[p].lc = update(tree[p].lc, l, mid, q);
	} else {
		tree[p].rc = update(tree[p].rc, mid + 1, r, q);
	}
	return p;
}

void dfs1(int u, int father) {
	depth[u] = depth[father] + 1;
	fa[u] = father;
	size[u] = 1;
	root[u] = update(root[fa[u]], 1, len, a[u]);
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].v;
		if (v != father) {
			dfs1(v, u);
			size[u] += size[v];
			if (size[v] > size[son[u]]) {
				son[u] = v;
			}
		}
	}
}

void dfs2(int u, int t) {
	top[u] = t;
	if (!son[u]) {
		return;
	}
	dfs2(son[u], t);
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].v;
		if (v != fa[u] && v != son[u]) {
			dfs2(v, v);
		}
	}
}

int lca(int x, int y) {
	int fx = top[x], fy = top[y];
	while (fx != fy) {
		if (depth[fx] >= depth[y]) {
			x = fa[fx];
			fx = top[x];
		} else {
			y = fa[fy];
			fy = top[y];
		}
	}
	if (depth[x] <= depth[y]) {
		return x;
	} else {
		return y;
	}
}

int query(int x, int y, int f, int gf, int l, int r, int k) {
	if (l == r) {
		return l;
	}
	int mid = (l + r) >> 1;
	int val = tree[tree[x].lc].val + tree[tree[y].lc].val - tree[tree[f].lc].val - tree[tree[gf].lc].val;
	if (val >= k) {
		return query(tree[x].lc, tree[y].lc, tree[f].lc, tree[gf].lc, l, mid, k);
	} else {
		return query(tree[x].rc, tree[y].rc, tree[f].rc, tree[gf].rc, mid + 1, r, k - val);
	}
}

int main() {
	//freopen("tmp.in", "r", stdin);
	//freopen("tmp.out", "w", stdout);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		a[i] = b[i] = read();
	}
	sort(b + 1, b + n + 1);
	len = unique(b + 1, b + n + 1) - b - 1;
	for (int i = 1; i <= n; i++) {
		a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
	}
	for (int i = 1; i < n; i++) {
		int u = read(), v = read();
		addEdge(u, v);
		addEdge(v, u);
	}
	/*
    for (int i = 1; i <= n; i++) {
    	cout << b[i] << " ";
	}
	puts("");
	*/
	dfs1(1, 0);
	dfs2(1, 1);
	int last = 0;
	for (int i = 1; i <= m; i++) {
		int u = read(), v = read(), k = read();
		u ^= last;
		int anc = lca(u, v);
		last = b[query(root[u], root[v], root[anc], root[fa[anc]], 1, len, k)];
		cout << last << endl;
	}
	/*
	for (int i = 1; i <= n; i++) {
		cout << root[i] << " ";
	}
	*/
	return 0;
}
2021/8/1 11:16
加载中...