标签:pos 子节点 roo 开始学习 技术分享 水题 树状数组 href 分享图片
树链剖分就是将树分割成多条链,然后利用数据结构(线段树、树状数组等)来维护这些链。
void dfs1(ll x,ll pre)
{
ll siz=G[x].size();
sz[x]++;
dep[x]=dep[pre]+1;
fa[x]=pre;
for(ll i=0,p=G[x][i]; i<siz; i++,p=G[x][i]) {
if(p==pre) continue;
dfs1(p,x);
sz[x]+=sz[p];
if(sz[p]>sz[son[x]]) son[x]=p;//更新重儿子
}
}
void dfs2(ll x,ll t,ll pre)
{
top[x]=t;//继承父亲的top
dfn[++tot]=x;
pos[x]=tot;
if(!son[x]) return;
dfs2(son[x],t,x);//优先更新重儿子
ll siz=G[x].size();
for(int i=0,p=G[x][i]; i<siz; i++,p=G[x][i]) {
if(p==pre||p==son[x]) continue;
dfs2(p,p,x);//从之前的结论我们可以看出轻边上的叶子节点必然是top节点,即轻链底端必定是top节点
}
}
ll solve(ll x,ll y)
{
ll ans=0,fx,fy;
for(fx=top[fa[x]],fy=fa[top[y]]; fx!=fy; fx=top[fa[x]]) {
ans+=query(root,1,maxn,pos[fx],pos[fy],0);
if(dep[fx]<dep[fy]) swap(fx,fy);//可以理解为从深度更深的往上快速跳转
}
if(pos[fx]>pos[fy]) swap(fx,fy);
ans+=query(root,1,maxn,pos[fx],pos[fy],0);
return ans;
}
标签:pos 子节点 roo 开始学习 技术分享 水题 树状数组 href 分享图片
原文地址:https://www.cnblogs.com/KatouKatou/p/9557540.html