主席树 Re 4 个点求调,悬关
查看原帖
主席树 Re 4 个点求调,悬关
563650
haochengw920楼主2024/1/14 22:49

rt,调了好久了(悲

#include<cstdio>
#include<vector>
#include<algorithm>
#define int long long
using namespace std;

const int MAXN = 100005;

int n, Q, lst;
int d[MAXN], val[MAXN];

bool fg = false;

inline void Init() {
	vector<int>tmp;
	for (int i = 1; i <= n; ++ i)
		tmp.push_back(val[i]);
	sort(tmp.begin(), tmp.end());
	tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
	int sz = tmp.size();
	for (int i = 0; i < sz; ++ i) d[i + 1] = tmp[i];
	for (int i = 1; i <= n; ++ i)
		val[i] = lower_bound(tmp.begin(), tmp.end(), val[i]) - tmp.begin() + 1;  
}
namespace President_tree {
	#define lc tr[u].l
	#define rc tr[u].r
	int idx, rt[MAXN];
	struct node {
		int sum, l, r;
	}tr[MAXN * 25];
	inline void push_up(int u) {
		tr[u].sum = tr[lc].sum + tr[rc].sum;
	}
	inline int Clone(int u) {
		if (idx >= MAXN * 25 - 20) puts("---"), exit(0);
		tr[++ idx] = tr[u];
		return idx;
	}
	inline int Modify(int u, int p, int x, int l = 1, int r = n) {
		u = Clone(u);
		if (l == r) {
			tr[u].sum += x;
			return u;
		}
		int mid = (l + r) >> 1;
		if (p <= mid) lc = Modify(lc, p, x, l, mid);
		else rc = Modify(rc, p, x, mid + 1, r);
		push_up(u); return u;
	}
	inline int Query(int a, int b, int c, int d, int K, int l = 1, int r = n) {
		if (l == r) return l;
		int mid = (l + r) >> 1;
		int sz = tr[tr[a].l].sum + tr[tr[b].l].sum - tr[tr[c].l].sum - 2 * tr[tr[d].l].sum;
		if (sz >= K) return Query(tr[a].l, tr[b].l, tr[c].l, tr[d].l, K, l, mid);
		else return Query(tr[a].r, tr[b].r, tr[c].r, tr[d].r, K - sz, mid + 1, r);
	}
	#undef lc
	#undef rc
}
using namespace President_tree;
namespace Graph {
	struct edge {
		int to, nex;
	}e[MAXN << 1]; int idx, head[MAXN];
	inline void add(int u, int v) {
		e[++ idx].to = v;
		e[idx].nex = head[u];
		head[u] = idx;
	}
	int dep[MAXN], fa[MAXN][25];
	inline void dfs(int u) {
		dep[u] = dep[fa[u][0]] + 1;
		for (int i = 1; i <= 20; ++ i)
			fa[u][i] = fa[fa[u][i - 1]][i - 1];
		rt[u] = Modify(rt[fa[u][0]], val[u], 1);
		for (int i = head[u]; i; i = e[i].nex) {
			int v = e[i].to;
			if (v == fa[u][0]) continue;
			fa[v][0] = u;
			dfs(v);
		}
	}
	inline int Lca(int u, int v) {
		if (dep[v] > dep[u]) swap(u, v);
		for (int i = 20; ~i; -- i)
			if (dep[v] <= dep[fa[u][i]])
				u = fa[u][i];
		if (u == v) return u;
		for (int i = 20; ~i; -- i)
			if (fa[u][i] != fa[v][i])
				u = fa[u][i], v = fa[v][i];
		return fa[u][0];
	}
}
using namespace Graph;

signed main()
{
	scanf ("%lld%lld", &n, &Q);
	for (int i = 1; i <= n; ++ i)
		scanf ("%lld", val + i);
	int u, v, k, lca;
	for (int i = 1; i < n; ++ i) {
		scanf ("%lld%lld", &u, &v);
		add(u, v); add(v, u);
	}
	Init(); dfs(1);
	while (Q --) {
		scanf ("%lld%lld%lld", &u, &v, &k);
		u ^= lst; lca = Lca(u, v); 
		int x = Query(rt[u], rt[v], rt[lca], rt[fa[lca][0]], k);
		printf ("%lld\n", lst = d[Query(rt[u], rt[v], rt[lca], rt[fa[lca][0]], k)]);
	}
	return 0;
}
2024/1/14 22:49
加载中...