给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
Input
第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。
Output
M行,表示每个询问的答案。最后一个询问不输出换行符
Sample Input
8 5 105 2 9 3 8 5 7 7 1 2 1 3 1 4 3 5 3 6 3 7 4 8 2 5 1 0 5 2 10 5 3 11 5 4 110 8 2
Sample Output
2 8 9 105 7
Hint
HINT:
N,M<=100000
暴力自重。。。
标准的树上路径第k大模板题
路径保存,根据父亲建树
root【L】+root【R】-root【lca(L,R)】-root【fa【lca(L,R) 】】;
注意!!!题上给的边是无向边
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+10;
int T[maxn],L[maxn*44],R[maxn*44],sum[maxn*44];
int a[maxn],b[maxn],f[maxn][22],dep[maxn],e,len,tot;
int to[maxn*2],head[maxn],nxt[maxn*2];
void add(int u,int v)
{
e++;
to[e]=v;
nxt[e]=head[u];
head[u]=e;
}
void build(int &rt,int l,int r)
{
rt=++tot;
sum[rt]=0;
if(l==r) return ;
int mid=(l+r)/2;
build(L[rt],l,mid);
build(R[rt],mid+1,r);
}
void update(int &rt,int pre,int l,int r,int x)
{
rt=++tot;
L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+1;
if(l==r) return ;
int mid=(l+r)/2;
if(x<=mid) update(L[rt],L[pre],l,mid,x);
else update(R[rt],R[pre],mid+1,r,x);
}
int query(int gen_fa,int gen,int ql,int qr,int l,int r,int k)
{
if(l==r) return l;
int res=sum[L[ql]]+sum[L[qr]]-sum[L[gen_fa]]-sum[L[gen]];
int mid=(l+r)/2;
if(res>=k) return query(L[gen_fa],L[gen],L[ql],L[qr],l,mid,k);
else return query(R[gen_fa],R[gen],R[ql],R[qr],mid+1,r,k-res);
}
void dfs(int v,int fa)
{
f[v][0]=fa;
dep[v]=dep[fa]+1;
update(T[v],T[fa],1,len,lower_bound(b+1,b+len+1,a[v])-b);
for(int i=1;(1<=0;i--)
{
if(f[u][i]!=f[v][i])
{
u=f[u][i];
v=f[v][i];
}
}
return f[u][0];
}
int main()
{
memset(head,-1,sizeof head);
e=tot=0;
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
len=unique(b+1,b+n+1)-b-1;
build(T[0],1,len);
for(int i=1;i<=n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(1,0);
int ans=0;
while(m--)
{
int ql,qr,k;
scanf("%d%d%d",&ql,&qr,&k);
ql=ql^ans;
int gen=lca(ql,qr);
ans=b[query(T[f[gen][0]],T[gen],T[ql],T[qr],1,len,k)];
if(m!=0) printf("%d\n",ans);
else printf("%d",ans);
}
return 0;
}