离散化
对每个节点,用线段树表示该节点到根的路径上的值域
然后可持久化
询问的时候查询u,v,LCA(u,v),fa[ LCA(u,v)]结点上的四棵线段树
做一做减法就好
notice:
1、初始的权值已经超过了int,需要long long
2、最后一组询问的换行符不要输出!(我已经邮件了一发管理员希望他改题面)
写起来很好写
#include
#include
#include
#include
#define mid ((l+r)>>1)
#define LOG 20
#define N 200050
using namespace std;
typedef long long LL;
int tr[40*N],ls[40*N],rs[40*N];
LL a[N],d[N],ans;
int h[N],D[N],cur[N];
int Jump[N][LOG+5];
int n,m,cnt,v,x;
vector<int> e[N];
bool cmp(int p1,int p2) { return a[p1] < a[p2]; }
void ins(int l,int r,int las,int &t) {
if (!t) t = ++cnt;
if (l == r) { tr[t] = tr[las] + v; return ; }
if (x <= mid)
ins(l,mid,ls[las],ls[t]) , rs[t] = rs[las];
else
ins(mid+1,r,rs[las],rs[t]) , ls[t] = ls[las];
tr[t] = tr[ ls[t] ] + tr[ rs[t] ];
}
void dfs(int u,int fa) {
Jump[u][0] = fa; D[u] = D[ fa ] + 1;
x = a[u]; v = 1;
ins(1,n,h[fa],h[u]);
for (int i=0;i<(int)e[u].size();i++)
if (e[u][i] != fa) dfs(e[u][i],u);
}
void _preLCA() {
for (int i=1;i<=LOG;i++)
for (int j=1;j<=n;j++)
Jump[j][i] = Jump[ Jump[j][i-1] ][i-1];
}
int LCA(int x,int y) {
if (D[x] < D[y]) swap(x,y);
for (int i=LOG;i>=0;i--)
if (D[ Jump[x][i] ] >= D[y]) x = Jump[x][i];
if (x == y) return x;
for (int i=LOG;i>=0;i--)
if (Jump[x][i] != Jump[y][i])
x = Jump[x][i] , y = Jump[y][i];
return Jump[x][0];
}
//p1 --> u , p2 --> v , p3 --> LCA
void query(int l,int r,int p1,int p2,int p3,int p4,int k) {
if (l == r) { ans = l; return ; }
int cur = tr[ ls[p1] ] + tr[ ls[p2] ] - tr[ ls[p3] ] - tr[ ls[p4] ];
if (cur >= k)
query(l,mid,ls[p1],ls[p2],ls[p3],ls[p4],k);
else
query(mid+1,r,rs[p1],rs[p2],rs[p3],rs[p4],k-cur);
}
int main() {
#ifndef ONLINE_JUDGE
// freopen("1.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
for (int i=1;i<=n;i++) cur[i] = i;
sort(cur+1,cur+n+1,cmp);
//离散化
for (int i=1;i<=n;i++)
d[i] = a[ cur[i] ] , a[ cur[i] ] = i;
for (int _=1;_<=n-1;_++) {
int x,y; scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
//建树
dfs(1,0);
_preLCA();
// ans = 0;
for (int _=1;_<=m;_++) {
LL u,v,k;
scanf("%lld%lld%lld",&u,&v,&k);
u ^= ans;
int p = LCA(u,v);
query(1,n,h[u],h[v],h[p],h[ Jump[p][0] ],k);
printf("%lld",d[ans]);
if (_!=m) printf("\n");
ans = d[ans];
}
return 0;
}