• P2147 [SDOI2008]洞穴勘测


    传送门

    维护森林中点之间的连通性,有加边和删边操作,保证不出现环

    显然直接 $LCT$ 维护,模板套进去就好了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e5+7,M=1e6+7;
    int c[N][2],fa[N];
    bool rev[N];
    inline void pushdown(int x)
    {
        if(!rev[x]||!x) return;
        int &lc=c[x][0],&rc=c[x][1];
        rev[x]=0; swap(lc,rc);
        if(lc) rev[lc]^=1;
        if(rc) rev[rc]^=1;
    }
    inline void rever(int x) { rev[x]^=1; pushdown(x); }
    inline bool notroot(int x) { return (c[fa[x]][0]==x)|(c[fa[x]][1]==x); }
    inline void rotate(int x)
    {
        int y=fa[x],z=fa[y],d=(c[y][1]==x);
        if(notroot(y)) c[z][c[z][1]==y]=x;
        fa[x]=z; fa[y]=x; fa[c[x][d^1]]=y;
        c[y][d]=c[x][d^1]; c[x][d^1]=y;
    }
    inline void push_rev(int x)
    {
        if(notroot(x)) push_rev(fa[x]);
        else pushdown(x);
        pushdown(c[x][0]); pushdown(c[x][1]);
    }
    inline void splay(int x)
    {
        push_rev(x);
        while(notroot(x))
        {
            int y=fa[x],z=fa[y];
            if(notroot(y))
            {
                if(c[y][0]==x ^ c[z][0]==y) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    inline void access(int x)
    {
        for(int y=0;x;y=x,x=fa[x])
            splay(x),c[x][1]=y;
    }
    inline void makeroot(int x) { access(x); splay(x); rever(x); }
    inline int findroot(int x)
    {
        access(x); splay(x); pushdown(x);
        while(c[x][0]) x=c[x][0],pushdown(x);
        splay(x);
        return x;
    }
    inline void link(int x,int y) { makeroot(x); if(findroot(y)!=x) fa[x]=y; }
    inline void cut(int x,int y)
    {
        makeroot(x);
        if(findroot(y)!=x||fa[y]!=x||c[y][0]) return;
        fa[y]=c[x][1]=0;
    }
    int n,m;
    int main()
    {
        int a,b; char s[17];
        n=read(),m=read();
        while(m--)
        {
            scanf("%s",s); a=read(),b=read();
            if(s[0]=='C') { link(a,b); continue; }
            if(s[0]=='D') { cut(a,b); continue; }
            if(findroot(a)==findroot(b)) printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
  • 相关阅读:
    《C++ Primer(第五版)》知识巩固
    Ubuntu下配置安装Hadoop 2.2
    Golang框架beego和bee的开发使用
    C++下混合编译c语言方法总结
    算法导论学习笔记1---排序算法(平台:gcc 4.6.7)
    基于web端去除空格小工具
    Google Map API抓取地图坐标信息小程序
    【算法导论】散列表
    【算法导论】二叉搜索树
    【算法导论】基本数据结构
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/10631012.html
Copyright © 2020-2023  润新知