fastle
垆边人似月 皓腕凝霜雪
posts - 134,comments - 26,views - 27764
  • 把1的父亲设成了1导致debug半天
/*
惊奇的发现我不会写树上主席树QAQ
并不是进行链剖, 而是继承父亲, 然后根据主席树的可减性来求解
求lca可是还是要剖的

*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define ll long long
#define mmp make_pair
#define M 100010
using namespace std;
int read() {
	int nm = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
	return nm * f;
}
int a[M], b[M], c[M], rt[M], fa[M], top[M], sz[M], deep[M], son[M], n, q, cnt, ans;
vector<int> to[M];

int ls[M * 44], rs[M * 44], t[M * 44];

void dfs(int now, int f) {
	fa[now] = f;
	sz[now] = 1;
	deep[now] = deep[f] + 1;
	for(int i = 0; i < to[now].size(); i++) {
		int vj = to[now][i];
		if(vj == f) continue;
		dfs(vj, now);
		sz[now] += sz[vj];
		if(sz[son[now]] < sz[vj]) son[now] = vj;
	}
}


void modify(int l, int r, int last, int &now, int k) {
	now = ++cnt;
	t[now] = t[last] + 1;
	ls[now] = ls[last];
	rs[now] = rs[last];
	if(l == r) return;
	int mid = (l + r) >> 1;
	if(k <= mid) modify(l, mid, ls[last], ls[now], k);
	else modify(mid + 1, r, rs[last], rs[now], k);
}

int query(int l, int r, int rt1, int rt2, int rt3, int rt4, int k) {
	if(l == r) return l;
	int mid = (l + r) >> 1;
	int v = t[ls[rt3]] + t[ls[rt4]] - t[ls[rt1]] - t[ls[rt2]];
	if(k > v) return query(mid + 1, r, rs[rt1], rs[rt2], rs[rt3], rs[rt4], k - v);
	else return query(l, mid, ls[rt1], ls[rt2], ls[rt3], ls[rt4], k);
}

void dfs(int now) {
	modify(1, n, rt[fa[now]], rt[now], a[now]);
	if(son[now]) {
		top[son[now]] = top[now];
		dfs(son[now]);
	}
	for(int i = 0; i < to[now].size(); i++) {
		int vj = to[now][i];
		if(vj == fa[now] || vj == son[now]) continue;
		top[vj] = vj;
		dfs(vj);
	}
}

int lca(int a, int b) {
	for(; top[a] != top[b]; a = fa[top[a]]) {
		if(deep[top[a]] < deep[top[b]]) swap(a, b);
	}
	if(deep[a] > deep[b]) swap(a, b);
	return a;
}

int main() {
	n = read(), q = read();
	for(int i = 1; i <= n; i++) a[i] = b[i] = read();
	sort(b + 1, b + n + 1);
	for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
	for(int i = 1; i < n; i++) {
		int vi = read(), vj = read();
		to[vi].push_back(vj);
		to[vj].push_back(vi);
	}
	dfs(1, 0);
	top[1] = 1;
	dfs(1);
	while(q--) {
		int vi = read() ^ ans, vj = read(), k = read();
		int l = lca(vi, vj);
		ans = b[query(1, n, rt[l], rt[fa[l]], rt[vi], rt[vj], k)];
		cout << ans << "\n";
	}
	return 0;
}
/*
8 1
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
1 4 4
*/

posted on   fastle  阅读(138)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 内存占用高分析
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 一个超经典 WinForm,WPF 卡死问题的终极反思
阅读排行:
· 支付宝事故这事儿,凭什么又是程序员背锅?有没有可能是这样的...
· 在线客服系统 QPS 突破 240/秒,连接数突破 4000,日请求数接近1000万次,.NET 多
· C# 开发工具Visual Studio 介绍
· 在 Windows 10 上实现免密码 SSH 登录
· C#中如何使用异步编程
< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示