lxhgww的奇思妙想
长链剖分求K级祖先模板题。疯狂爆栈。。把dfs都加了个inline就过了。。这可能是信仰的力量吧。。
#include <bits/stdc++.h>
using namespace std;
const int maxn=300005;
struct edge{
int to,next;
}e[maxn<<1];
int head[maxn];
int cnt;
void init(){
cnt=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v){
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
int n,q;
int depth[maxn];
int mdepth[maxn];
int f[maxn][21];
int mc[maxn];
int linkh[maxn];
int len[maxn];
vector<int>up[maxn];
vector<int>dn[maxn];
inline void dfs(int u,int fa){
depth[u]=depth[fa]+1;
mdepth[u]=depth[u];
f[u][0]=fa;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
dfs(v,u);
mdepth[u]=max(mdepth[u],mdepth[v]);
if(mc[u]==-1||mdepth[v]>mdepth[mc[u]])mc[u]=v;
}
}
inline void dfs2(int u,int fa){
if(linkh[u]==-1)linkh[u]=u;
len[linkh[u]]++;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
if(v==mc[u])linkh[v]=linkh[u];
dfs2(v,u);
}
if(linkh[u]==u){
int upu=u,dnu=u;
for(int i=0;i<len[u];i++,upu=f[upu][0],dnu=mc[dnu]){
up[u].push_back(upu);
dn[u].push_back(dnu);
}
}
}
inline void pre(){
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++){
up[i].clear();
dn[i].clear();
mc[i]=linkh[i]=-1;
len[i]=0;
}
dfs(1,0);
dfs2(1,0);
for(int j=1;j<=20;j++){
for(int i=1;i<=n;i++){
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
int query(int x,int y){
if(depth[x]<=y)return 0;
if(y==0)return x;
int j=31-__builtin_clz(y);
x=f[x][j];
y-=(1<<j);
y-=(depth[x]-depth[linkh[x]]);
x=linkh[x];
if(y>=0)return up[x][y];
else return dn[x][-y];
}
int main(){
init();
scanf("%d",&n);
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
pre();
scanf("%d",&q);
int last=0;
int a,b;
for(int i=1;i<=q;i++){
scanf("%d%d",&a,&b);
a^=last,b^=last;
last=query(a,b);
printf("%d\n",last);
}
}