首页 > 其他分享 >CF1137F Matches Are Not a Child's Play 题解

CF1137F Matches Are Not a Child's Play 题解

时间:2023-02-06 20:34:01浏览次数:47  
标签:rt CF1137F 题解 top odt Matches int dfn read

以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前。

记每个点子树中的最大值为 \(f_x\),那么一个点的排名,首先就需要加上 \(<f_x\) 的所有值,记对应 \(f_x\) 的点为 \(y\),那么 \(y\) 一定会一路上来删掉 \(x\)。

所以一个点排名就是 \(<f_x\) 的所有值,再加上 \(x,y\) 之间的距离。

考虑如何维护修改,设上一个根是 \(rt\),新根是 \(x\),那么等价于一次换根,需要将 \(x\) 到 \(rt\) 这条路径 cover 上 \(p_{rt}\),同时改掉 \(x\) 的值。

可以使用 ODT + 树剖维护。

Code
const int N=2e5+5;
int n,m;
vi G[N];
int dep[N],siz[N],top[N],son[N],dfn[N],fat[N],dfc,p[N*2],rp[N*2];
void dfs1(int u,int fa) {
    dep[u]=dep[fa]+1,siz[u]=1,fat[u]=fa;
    for(int v:G[u]) if(v!=fa) {
        dfs1(v,u),siz[u]+=siz[v];
        p[u]=max(p[u],p[v]);
        if(siz[son[u]]<siz[v]) son[u]=v;
    }
}
void dfs2(int u,int tp,int fa) {
    top[u]=tp,dfn[u]=++dfc;
    if(son[u]==0) return;
    dfs2(son[u],tp,u);
    for(int v:G[u]) if(v!=fa&&v!=son[u]) dfs2(v,v,u);
}
int bit[2*N];
void add(int x,int v) { for(;x<=n+m;x+=(x&-x)) bit[x]+=v; }
int ask(int x) { int ret=0; for(;x;x-=(x&-x)) ret+=bit[x]; return ret; }
struct node {
    int l,r,v;
    node() {}
    node(int L,int R,int V) { l=L,r=R,v=V; }
    bool operator < (const node &a) const { return l<a.l; }
};
set<node> odt;
auto spilt(int p) {
    auto it=odt.lower_bound(node(p,-1,0));
    if(it!=odt.end()&&it->l==p) return it;
    --it;
    int l=it->l,r=it->r,v=it->v;
    odt.erase(it),odt.insert(node(l,p-1,v));
    return odt.insert(node(p,r,v)).fi;
}
void cover(int l,int r,int v) {
    auto itr=spilt(r+1),itl=spilt(l);
    for(auto it=itl;it!=itr;it=odt.erase(it)) add(it->v,-((it->r)-(it->l)+1));
    add(v,r-l+1),odt.insert(node(l,r,v));
}
void update(int u,int v,int w) {
    while(top[u]!=top[v]) {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        cover(dfn[top[u]],dfn[u],w),u=fat[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    cover(dfn[u],dfn[v],w);
}
int lca(int u,int v) {
    while(top[u]!=top[v]) {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        u=fat[top[u]];
    }
    return dep[u]<dep[v]?u:v;
}
int dist(int u,int v) { return dep[u]+dep[v]-2*dep[lca(u,v)]+1; }
int query(int x) {
    auto pos=odt.upper_bound(node(dfn[x],-1,0));
    int val=prev(pos)->v;
    return ask(val-1)+dist(x,rp[val]);
}
int main() {
    n=read(),m=read();
    FOR(i,1,n-1) {
        int x=read(),y=read();
        G[x].pb(y),G[y].pb(x);
    }
    FOR(i,1,n) p[i]=rp[i]=i;
    int rt=n,mx=n;
    dfs1(n,0),dfs2(n,n,0);
    FOR(i,1,n) add(p[i],1),odt.insert(node(dfn[i],dfn[i],p[i]));
    FOR(i,1,m) {
        string ch; cin>>ch;
        int u=read();
        if(ch[0]=='1') {
            if(u!=rt) update(rt,u,mx);
            ++mx,cover(dfn[u],dfn[u],mx),rp[mx]=rt=u;
        }
        else if(ch[0]=='2') printf("%d\n",query(u));
        else { int v=read(); printf("%d\n",query(u)>query(v)?v:u);}
    }
}

标签:rt,CF1137F,题解,top,odt,Matches,int,dfn,read
From: https://www.cnblogs.com/cnyzz/p/17096622.html

相关文章

  • robotframe环境搭建及问题解决
     1.安装pipinstallrobotframeworkipinstallrobotframework-ride进入C:\Python37\Scripts目录下,右击ride.py,选择使用python打开。出现RIDE界面表示RIDE安装成功。......
  • ABC288 EFG 题解
    E注意到后面选对前面的答案没有影响,而且前面选的顺序对后面的影响是连续的一段(如选2个,那么对应的\(c\)就应该是\(c[i-2..i]\)(对应\(i\)是1、2、3个选时的答案))然......
  • P3215 [HNOI2011]括号修复题解
    发现题解里的维护前后缀最大最小值的做法都是感性理解,所以我就来写个证明。将(看做\(-1\),)看做\(1\),首先几个变量:\(n\)代表括号序列的长度。\(a_i\)代表前缀和......
  • CF884D 题解
    题目传送门题目分析开始还真没看出来这题跟\(\text{P1090}\)合并果子的关系。其实只要逆向思考,把拆分看成效果一样的合并就可以了。而与合并果子不同的是,在这题当中......
  • abc285h题解
    考虑容斥,强制要求\(k\)个数为完全平方数,系数为\((-1)^k*C_n^k\)(因为我们要从\(n\)个数选出\(k\)个数作为完全平方数)。则在唯一分解\(p_1^{e_1}...p_n^{e_n}\)中,\(e_1...e_n......
  • "_OBJC_CLASS_$ [文件名1]referenced from in[文件名2]:ld: symbol(s) not found问题
    说实话开发一年多了,遇到了至少三次以上这种问题,很困惑,也很难搞觉得,其实很简单解决办法,在buildPhases中添加文件名1的.m文件即可了。"_OBJC_CLASS_$"PackageTourCustomAnnot......
  • 【题解】20230204解题报告
    解题报告20230204主要学习内容有:动态规划,字符串操作(在另外一篇文章里)T1:P5322[BJOI2019]排兵布阵首先题意是设定有n座城堡,s个玩家(不包括特殊玩家),此时每名玩家都有m......
  • lg9035题解
    考虑枚举\(a_{n-1}=l\),根据题意\(l\leqa_n\leqk+1-l\),这说明\(a_n\)有\(k+1-2l\)种取值。令\(b_i=a_i-a_{i-1}\),则\(b_1\geq1\),\(b_i\geq0(i>1)\),\(b_1+...+b_{n-1}=l......
  • 洛谷P9035 Pont des souvenirs 题解
    题面很简洁,这里不做多说。70pts做法首先考虑到\(a_{n-1}\)和\(a_n\)两项是整个数列\(a\)中的最大的两项,所以若\(a_{n-1}+a_n\)不超过\(k+1\),则数列中任意两项......
  • P2016题解
    P2016题解题目描述Bob要建立一个古城堡,城堡中的路形成一棵无根树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能瞭望到所有的路。注意,某个士兵在一个结点上时......