zoukankan      html  css  js  c++  java
  • SP8791 DYNALCA

    SP8791 DYNALCA - Dynamic LCA

    有一个森林最初由 (n (1 le n le 100000)) 个互不相连的点构成

    你需要处理以下操作:

    • link A B:添加从顶点A到B的边,使A成为B的子节点,其中保证A是一个根顶点,A和B在不同的树中。
    • cut A:切断点A到其父节点的边,保证A是一个非根节点。
    • lca A B:输出A和B的最近共同祖先,保证A和B在同一棵树中。

    最开始我是这么写的

    void LCA(int x,int y)
    {
        access(x),splay(x),splay(y);
        while(par[y]) y=par[y],splay(y);
        printf("%d
    ",y);
    }
    

    然后一直T

    改成这个

    int access(int now)
    {
        int las=0;
        for(;now;las=now,now=fa)
            splay(now),rs=las;
        return las;
    }
    void LCA(int x,int y)
    {
        access(x);
        printf("%d
    ",access(y));
    }
    

    就过了

    恩,需要虚实边转换,否则复杂度是假的

    huyufeifei orz告诉我了这个问题


    Code:

    #include <cstdio>
    #include <cctype>
    #define fa par[now]
    #define rs ch[now][1]
    const int N=1e5+10;
    template <class T>
    inline void read(T &x)
    {
        x=0;char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
    }
    int ch[N][2],par[N];
    bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
    int identity(int now){return ch[fa][1]==now;}
    void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
    void Rotate(int now)
    {
        int p=fa,typ=identity(now);
        connect(p,ch[now][typ^1],typ);
        if(isroot(p)) connect(par[p],now,identity(p));
        else fa=par[p];
        connect(now,p,typ^1);
    }
    void splay(int now)
    {
        for(;isroot(now);Rotate(now))
            if(isroot(fa))
                Rotate(identity(now)^identity(fa)?now:fa);
    }
    int access(int now)
    {
        int las=0;
        for(;now;las=now,now=fa)
            splay(now),rs=las;
        return las;
    }
    void LCA(int x,int y)
    {
        access(x);
        printf("%d
    ",access(y));
    }
    void Link(int x,int y)
    {
        access(x),splay(x);
        par[x]=y;
    }
    void cat(int x)
    {
        access(x),splay(x);
        par[ch[x][0]]=0;
        ch[x][0]=0;
    }
    int main()
    {
        int n,m;char op[23];
        read(n),read(m);
        for(int x,y,i=1;i<=m;i++)
        {
            scanf("%s",op);
            if(op[1]=='i') read(x),read(y),Link(x,y);
            else if(op[1]=='u') read(x),cat(x);
            else read(x),read(y),LCA(x,y);
        }
        return 0;
    }
    

    2019.3.10

  • 相关阅读:
    MSBuild最佳实践
    Javascript:阻止浏览器默认右键事件,并显示定制内容
    zeptoJS:如何像jQuery一样,让滚动变得优雅?
    Javascript:DOM表格操作
    Javascript:getElementsByClassName
    Javascript:DOM动态创建元素实例应用
    Javascript:倒计时
    Javascript:sort()方法快速实现对数组排序
    探究css !important的应用之道
    Javascript:splice()方法实现对数组元素的插入、删除、替换及去重
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10506042.html
Copyright © 2011-2022 走看看