这题的题意告诉你,每次询问不超过10,说明我们只需要维护前10个即可,这样的话维护的大小就不多
因此可以直接树链剖分+线段树来做,但是还有个问题,不能直接套一个含log的数据结构进去,因为这样复杂度会多一个log,我之前用的set超时了
因此还是使用使用vector直接归并数组来做
#include<bits/stdc++.h> using namespace std; const int N=4e5+10; int h[N],ne[N],e[N],idx; int dfn[N],ins[N],low[N],times; int depth[N],fa[N],id[N],top[N],son[N],sz[N]; int n,m,q; vector<int> num[N]; struct arr{ int q[10],len; int size(){ return len; } void push_back(int x){ q[len++]=x; } void clear(){ for(int i=0;i<10;i++){ q[i]=0; } len=0; } }; struct node{ int l,r; arr s; }tr[N<<2]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int f){ sz[u]=1; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==f) continue; fa[j]=u; depth[j]=depth[u]+1; dfs(j,u); sz[u]+=sz[j]; if(sz[j]>sz[son[u]]) son[u]=j; } } void dfs1(int u,int x){ dfn[u]=++times; id[times]=u; top[u]=x; if(!son[u]) return; dfs1(son[u],x); int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa[u]||j==son[u]) continue; dfs1(j,j); } } arr merge(arr a,arr b){ arr d; d.clear(); int i=0,j=0; while(j<b.size()&&i<a.size()&&d.size()<10){ if(a.q[i]<b.q[j]) d.push_back(a.q[i++]); else d.push_back(b.q[j++]); } while(j<b.size()&&d.size()<10) d.push_back(b.q[j++]); while(i<a.size()&&d.size()<10) d.push_back(a.q[i++]); return d; } void build(int u,int l,int r){ if(l==r){ tr[u]={l,r}; int i; for(auto x:num[l]){ tr[u].s.push_back(x); if((int)tr[u].s.size()==10) break; } } else{ tr[u]={l,r}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); tr[u].s=merge(tr[u<<1].s,tr[u<<1|1].s); } } arr q1; void query(int u,int l,int r){ if(tr[u].l>=l&&tr[u].r<=r){ q1=merge(q1,tr[u].s); return ; } int mid=tr[u].l+tr[u].r>>1; if(l<=mid){ query(u<<1,l,r); } if(r>mid) query(u<<1|1,l,r); } void querypath(int x,int y,int z){ q1.clear(); while(top[x]!=top[y]){ if(depth[top[x]]<depth[top[y]]) swap(x,y); query(1,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(depth[x]>depth[y]) swap(x,y); query(1,dfn[x],dfn[y]); int k=min((int)q1.size(),z); printf("%d ",k); for(int i=0;i<k;i++){ printf("%d ",q1.q[i]); } printf(" "); } int main(){ //ios::sync_with_stdio(false); memset(h,-1,sizeof h); cin>>n>>m>>q; int i; for(i=1;i<n;i++){ int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } depth[1]=1; dfs(1,-1); dfs1(1,1); for(i=1;i<=m;i++){ int x; scanf("%d",&x); num[dfn[x]].push_back(i); } build(1,1,n); while(q--){ int u,v,a; scanf("%d%d%d",&u,&v,&a); querypath(u,v,a); } }