CF916E Jamie and Tree 题解

CF916E Jamie and Tree 题解

CF916E Jamie and Tree

题意

有一棵 n 个节点的有根树,标号为 1n,你需要维护以下三种操作

  1. 给一个点 v ,将整颗树的根变为 v

  2. 给两个点 u,v,将 lca(u,v) 所在的子树都加上 x

  3. 给一个点 v,问以 v 所在的子树的权值和。

分析

换根树剖板子题。设当前根为 rt ,有几种简单操作:

换根后 LCA

直接分讨即可。

int LCA(int x,int y)
{
    if(dep[x]>dep[y]) swap(x,y);
    int xr=lca(x,rt),yr=lca(y,rt),xy=lca(x,y);
    if(xy==x) 
    {
        if(xr==x){if(yr==y) return y;return yr;}
        return x;
    }
    if(xr==x) return x;if(yr==y) return y;
    if((xr==rt&&xy==yr)||(yr==rt&&xy==xr)) return rt;
    if(xr==yr) return xy;
    if(xy!=xr) return xr;return yr;
}

换根后子树修改

分几种情况讨论:

  1. urt

此时直接把所有点权都加上 x

  1. u 不是 rt 的祖先

此时情况如图所示,不难发现,无论 u 在哪,u 的子树都不变。

  1. urt 的祖先

此时情况如图所示,设 v 为是 rt 祖先的 u 的子节点,要想得到 v ,我们可以每次把 rt 向上跳重链,直到跳到 u 的子节点。可以发现,加的部分相当于整棵树刨掉 v 的子树,由于树剖之后子树内节点编号连续,所以可以用线段树区间修改,每次修改 [1,idv)(idv+cntv1,n]

此部分代码如下:

int get(int x,int y)
{
    int fx=top[x],fy=top[y];
    while(top[x]!=top[y])
    {
        if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y); //跳重链顶深度更深的
        if(fa[fx]==y) return fx; //已经找到了
        x=fa[fx],fx=top[x];
    }
    if(dep[x]>dep[y]) swap(x,y);
    return hson[x];
}
void update_subtree(int u,int k)
{
    if(u==rt) update(1,1,n,1,n,k); //对应情况1
    else if(lca(u,rt)!=u) update(1,1,n,id[u],id[u]+cnt[u]-1,k); //情况2
    else //情况3
    {
        int v=get(u,rt);
        if(id[v]-1>=1) update(1,1,n,1,id[v]-1,k);
        if(id[v]+cnt[v]<=n) update(1,1,n,id[v]+cnt[v],n,k);
    }
}

换根后子树求和

原理和子树修改相同。

int query_subtree(int u)
{
    int res=0;
    if(u==rt) res=query(1,1,n,1,n);
    else if(lca(u,rt)!=u) res=query(1,1,n,id[u],id[u]+cnt[u]-1);
    else
    {
        int v=get(u,rt);
        if(id[v]-1>=1) res+=query(1,1,n,1,id[v]-1);
        if(id[v]+cnt[v]<=n) res+=query(1,1,n,id[v]+cnt[v],n);
    }
    return res;
}

完整代码

Submission #153363241 - Codeforces

本文作者:l_x_y

本文链接:https://www.cnblogs.com/lxy-2022/p/CF916E-Solution.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   l_x_y  阅读(49)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开