原来的代码在 spoj 一直 CE,下面是 gpt 改了的代码,
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#define int long long
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define req(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
char buf[1 << 23], *p1 = buf, *p2 = buf;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
template <typename TP> inline TP read(TP &num)
{
TP x = 0;
int f = 0;
char ch = getchar();
while (ch < 48 || ch > 57) f |= ch == '-', ch = getchar();
while (48 <= ch && ch <= 57) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
return num = f ? -x : x;
}
template <typename TP> inline void write(TP x)
{
(x < 0) ? (putchar('-'), x = -x) : 0;
(x > 9) ? (write(x / 10), 0) : 0;
putchar((x % 10) ^ 48);
}
template <typename TP> inline void writeln(TP x)
{
write<TP>(x);
puts("");
}
int n, q, a[200001], u, v, w[200001], cnt, blksiz;
vector<int> g[200001];
struct Q
{
int l, r, k, id;
} query[200001];
int blk[601][601], st[601], bel[200001], num, tot[601];
int ap1[200001], ap2[200001], ans[200001], vis[200001];
inline void init()
{
num = n / blksiz + (n % blksiz ? 1 : 0);
rep(i, 1, num) st[i] = i * blksiz - blksiz + 1;
}
inline void epl(int val)
{
int pos = bel[val];
++blk[pos][val - st[pos] + 1];
++tot[pos];
}
inline void ers(int val)
{
int pos = bel[val];
--blk[pos][val - st[pos] + 1];
--tot[pos];
}
inline void prs(int val)
{
if (vis[val]) --vis[val], ers(w[val]);
else ++vis[val], epl(w[val]);
}
void dfs(int x, int fa)
{
a[++cnt] = x;
for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); ++it) if (*it != fa) dfs(*it, x);
a[++cnt] = x;
}
int fa[200001], dep[200001], siz[200001], top[200001], son[200001], idx;
int dfn[200001];
set<int> val;
int setvalcnt;
map<int, int> btos;
int stob[200001];
void tcs_dfs1(int x, int fa)
{
::fa[x] = fa;
dep[x] = dep[fa] + 1;
for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); ++it) if (*it != fa) tcs_dfs1(*it, x), siz[x] += siz[*it], (siz[*it] > siz[son[x]] ? son[x] = *it : 0);
++siz[x];
}
void tcs_dfs2(int x, int topfa)
{
top[x] = topfa;
dfn[x] = ++idx;
if (son[x]) tcs_dfs2(son[x], topfa);
for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); ++it) if (*it != fa[x] && *it != son[x]) tcs_dfs2(*it, *it);
}
inline int lca(int x, int y)
{
while (top[x] != top[y])
{
if (dep[top[x]] < dep[top[y]]) x ^= y ^= x ^= y;
x = fa[top[x]];
}
return dep[x] < dep[y] ? x : y;
}
inline int getans(int qr)
{
int ANS = 0;
int target = query[qr].k, sum = 0;
rep(i, 1, num)
{
sum += tot[i];
if (sum >= target)
{
sum = target - sum + tot[i];
rep(j, 1, blksiz)
{
sum -= blk[i][j];
if (sum <= 0)
{
ANS = st[i] + j - 1;
break;
}
}
if (ANS) break;
}
}
return ANS;
}
bool compare_query(const Q &a, const Q &b)
{
if (bel[a.l] != bel[b.l])
return a.l < b.l;
return (bel[a.l] % 2) ? (a.r < b.r) : (a.r > b.r);
}
signed main()
{
read(n), read(q);
blksiz = n / sqrt(q);
rep(i, 1, max(n * 2, q)) bel[i] = (i - 1) / blksiz + 1;
init();
rep(i, 1, n) read(w[i]), val.insert(w[i]);
for (set<int>::iterator it = val.begin(); it != val.end(); ++it) ++setvalcnt, btos[*it] = setvalcnt, stob[setvalcnt] = *it;
rep(i, 1, n) w[i] = btos[w[i]];
rep(i, 1, n - 1) read(u), read(v), g[u].push_back(v), g[v].push_back(u);
dfs(1, 0);
tcs_dfs1(1, 0);
tcs_dfs2(1, 1);
rep(i, 1, n * 2) if (!ap1[a[i]]) ap1[a[i]] = i; else ap2[a[i]] = i;
rep(i, 1, q)
{
read(query[i].l), read(query[i].r), read(query[i].k);
int qlca = lca(query[i].l, query[i].r);
if (ap1[query[i].l] > ap1[query[i].r]) swap(query[i].l, query[i].r);
if (qlca == query[i].l) query[i].l = ap1[query[i].l];
else query[i].l = ap2[query[i].l];
query[i].r = ap1[query[i].r];
query[i].id = i;
}
sort(query + 1, query + q + 1, compare_query);
int l = 1, r = 0;
rep(qr, 1, q)
{
while (r < query[qr].r) prs(a[++r]);
while (l > query[qr].l) prs(a[--l]);
while (r > query[qr].r) prs(a[r--]);
while (l < query[qr].l) prs(a[l++]);
int qlca = lca(a[l], a[r]);
if (qlca != a[l] && qlca != a[r]) prs(qlca), ans[query[qr].id] = getans(qr), prs(qlca);
else ans[query[qr].id] = getans(qr);
}
rep(i, 1, q) writeln(stob[ans[i]]);
return 0;
}