长链剖分练习
Posted uid001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了长链剖分练习相关的知识,希望对你有一定的参考价值。
练习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 ", ans=query(x,k)); } }
以上是关于长链剖分练习的主要内容,如果未能解决你的问题,请参考以下文章