給定一棵樹,每次詢問一個點的\(k\)次祖先,強制在線。
Vijoshtml
長鏈剖分。
連接暫時咕咕咕了。
如今能夠戳連接看題解了ios
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define ll long long #define MAX 300300 inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } struct Line{int v,next;}e[MAX<<1]; int h[MAX],cnt=1; inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;} int hson[MAX],dep[MAX],md[MAX],len[MAX]; int p[MAX][20],top[MAX],n,hbit[MAX]; void dfs1(int u,int ff) { md[u]=dep[u]=dep[ff]+1;p[u][0]=ff; for(int i=1;i<20;++i) if(p[u][i-1])p[u][i]=p[p[u][i-1]][i-1]; else break; for(int i=h[u];i;i=e[i].next) { int v=e[i].v;if(v==ff)continue; dfs1(v,u); if(md[v]>md[hson[u]])hson[u]=v,md[u]=md[v]; } } void dfs2(int u,int tp) { top[u]=tp;len[u]=md[u]-dep[top[u]]+1; if(hson[u])dfs2(hson[u],tp); for(int i=h[u];i;i=e[i].next) if(e[i].v!=p[u][0]&&e[i].v!=hson[u]) dfs2(e[i].v,e[i].v); } vector<int> U[MAX],D[MAX]; int Query(int u,int k) { if(k>dep[u])return 0;if(!k)return u; u=p[u][hbit[k]];k^=1<<hbit[k]; if(!k)return u; if(dep[u]-dep[top[u]]==k)return top[u]; if(dep[u]-dep[top[u]]>k)return D[top[u]][dep[u]-dep[top[u]]-k-1]; return U[top[u]][k-dep[u]+dep[top[u]]-1]; } int main() { n=read(); for(int i=1;i<n;++i) { int u=read(),v=read(); Add(u,v);Add(v,u); } dfs1(1,0);dfs2(1,1); for(int i=1;i<=n;++i) if(i==top[i]) { int l=0,x=i; while(l<len[i]&&x)x=p[x][0],++l,U[i].push_back(x); l=0,x=i; while(l<len[i])x=hson[x],++l,D[i].push_back(x); } int mx=1; for(int i=1;i<=n;++i) { if((i>>mx)&1)++mx; hbit[i]=mx-1; } int m=read(),ans=0; while(m--) { int u=read()^ans,v=read()^ans; printf("%d\n",ans=Query(u,v)); } return 0; }