练习1 给定树, 强制在线询问k级祖先
https://zhuanlan.zhihu.com/p/25984772
知乎介绍的挺详细的, 放个我打的板子
int n, m;
int sz[N], mx[N], dep[N], Log[N];
int fa[N][20], son[N], top[N];
vector<int> g[N], up[N], down[N];
void dfs(int x, int f, int d) {
sz[x]=1,mx[x]=dep[x]=d,fa[x][0]=f,son[x]=x;
for (int i=1; (1<<i)<dep[x]; ++i) {
fa[x][i] = fa[fa[x][i-1]][i-1];
}
for (int y:g[x]) if (y!=f) {
dfs(y,x,d+1);sz[x]+=sz[y];
if (mx[y]>mx[x]) son[x]=y,mx[x]=mx[y];
}
}
void dfs2(int x, int tf) {
top[x]=tf;
if (son[x]!=x) dfs2(son[x],tf);
for (int y:g[x]) if (y!=fa[x][0]&&y!=son[x]) dfs2(y,y);
}
void init() {
dfs(1,0,1),dfs2(1,1);
Log[0] = -1;
REP(i,1,n) Log[i]=Log[i>>1]+1;
REP(i,1,n) if (top[i]==i) {
int x = i;
REP(j,0,mx[i]-dep[i]) up[i].pb(x),x=fa[x][0];
x = i;
REP(j,0,mx[i]-dep[i]) down[i].pb(x),x=son[x];
}
}
int query(int x, int k) {
if (!k) return x;
if (k>=dep[x]) return 0;
x = fa[x][Log[k]], k ^= 1<<Log[k];
if (dep[x]-dep[top[x]]>=k) return down[top[x]][dep[x]-dep[top[x]]-k];
return up[top[x]][k-dep[x]+dep[top[x]]];
}
int main() {
scanf("%d", &n);
REP(i,2,n) {
int u, v;
scanf("%d%d", &u, &v);
g[u].pb(v),g[v].pb(u);
}
init();
int ans = 0;
scanf("%d", &m);
REP(i,1,m) {
int x, k;
scanf("%d%d", &x, &k);
x ^= ans, k ^= ans;
printf("%d\n", ans=query(x,k));
}
}