树链剖分
作者:互联网
重链剖分
int dep[Z], siz[Z], dad[Z], kid[Z];//kid[rt]:rt的重儿子编号
int dfn[Z], tim, top[Z], rnk[Z];//top[rt]:rt所在重链的顶部节点; rnk[rt]:dfs序为rt的节点编号
void search(int rt, int fa)//寻找重边和重儿子
{
dad[rt] = fa, kid[rt] = 0;
dep[rt] = dep[fa] + 1, siz[rt] = 1;
int mxsz = 0;
for (re i = head[rt]; i; i = e[i].ne)
{
int son = e[i].to;
if (dep[son]) continue;
search(son, rt);
siz[rt] += siz[son];
if (mxsz < siz[son]) mxsz = siz[son], kid[rt] = son;//更新重儿子
}
}
void connect(int rt, int pa)//连接重边构成重链
{
dfn[rt] = ++tim; rnk[tim] = rt;
top[rt] = pa;
if (kid[rt]) connect(kid[rt], pa);//优先递归重儿子
for (re i = head[rt]; i; i = e[i].ne)
{
int son = e[i].to;
if (son == kid[rt] || son == dad[rt]) continue;
connect(son, son);//新建立一条重链
}
}
void modify(int x, int y, int val)//对从x到y的简单路径上的点权值加val
{
while (top[x] != top[y])//没在一条重链上
{
if (dep[top[x]] < dep[top[y]]) swap(x, y);
update(dfn[top[x]], dfn[x], val);
x = top[x];//向上翻
}
if (dep[x] > dep[y]) swap(x, y);
update(dfn[x], dfn[y], val);
}
int ask(int x, int y)//查询从x到y的简单路径上的点权值之和
{
while (top[x] != top[y])//没在一条重链上
{
if (dep[top[x]] < dep[top[y]]) swap(x, y);
ans += query(dfn[top[x]], dfn[x]);
x = top[x];//向上翻
}
if (dep[x] < dep[y]) swap(x, y);
ans += query(dfn[x], dfn[y]);
return ans;
}
标签:rt,剖分,int,top,son,dep,dfn,树链 来源: https://www.cnblogs.com/zsj11337/p/16368369.html