ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树链剖分

2022-06-12 17:32:24  阅读:123  来源: 互联网

标签:rt 剖分 int top son dep dfn 树链


重链剖分

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有