树剖+主席树,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;
}