[SDOI 2008] 洞穴勘测

Posted evenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI 2008] 洞穴勘测相关的知识,希望对你有一定的参考价值。

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=2049

[算法]

          LCT动态维护森林连通性

          时间复杂度 : O(NlogN ^ 2)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 300010

int n , m;

struct Link_Cut_Tree
{
    struct Node
    {
        int father , son[2];
        bool rev;
    } a[MAXN];
    inline void pushdown(int x)
    {
        if (a[x].rev)
        {
            swap(a[x].son[0] , a[x].son[1]);
            a[a[x].son[0]].rev ^= 1;
            a[a[x].son[1]].rev ^= 1;
            a[x].rev = false;
        }
    }
    inline bool get(int x)
    {
        pushdown(a[x].father);
        return a[a[x].father].son[1] == x;
    }
    inline bool nroot(int x)
    {
        return a[a[x].father].son[0] == x | a[a[x].father].son[1] == x;
    }
    inline void rotate(int x)
    {
        int f = a[x].father , g = a[f].father;                        
        int tmpx = get(x) , tmpf = get(f);
        int w = a[x].son[tmpx ^ 1];
        if (nroot(f)) a[g].son[tmpf] = x;
        a[x].son[tmpx ^ 1] = f;
        a[f].son[tmpx] = w;
        if (w) a[w].father = f;
        a[f].father = x;
        a[x].father = g;
    }
    inline void splay(int x)
    {
        int y = x , z = 0;
        static int st[MAXN];
        st[++z] = y;
        while (nroot(y))
            st[++z] = y = a[y].father;
        while (z) pushdown(st[z--]);
        while (nroot(x))
        {
            int y = a[x].father , z = a[y].father;
            if (nroot(y))
                rotate((a[y].son[0] == x) ^ (a[z].son[0] == y) ? (y) : (x));
            rotate(x);
        }
    }
    inline void access(int x)
    {
        for (int y = 0; x; x = a[y = x].father)
        {
            splay(x);
            a[x].son[1] = y;
        }
    }
    inline void make_root(int x)
    {
        access(x);
        splay(x);
        a[x].rev ^= 1;
    }
    inline void cut(int x , int y)
    {
        make_root(x);
        if (find_root(y) == x && a[x].father == y && !a[x].son[1])
            a[x].father = a[y].son[0] = 0;
    }
    inline void link(int x , int y)
    {
        make_root(x);
        if (find_root(y) != x) a[x].father = y;
    }
    inline int find_root(int x)
    {
        access(x);
        splay(x);
        while (a[x].son[0])
        {
            pushdown(x);
            x = a[x].son[0];
        }
        return x;
    }
} LCT;

int main()
{
    
    scanf("%d%d" , &n , &m);
    for (int i = 1; i <= m; i++)
    {
        char type[10];
        scanf("%s" , &type);
        if (type[0] == C)
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            LCT.link(x , y);    
        } else if (type[0] == D)
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            LCT.cut(x , y);
        } else
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            if (LCT.find_root(x) == LCT.find_root(y)) printf("Yes
");
            else printf("No
");
        }
    }
        
    return 0;
}

 

以上是关于[SDOI 2008] 洞穴勘测的主要内容,如果未能解决你的问题,请参考以下文章

LCTBZOJ2049 [SDOI2008]Cave 洞穴勘测

[SDOI2008]洞穴勘测

2049: [Sdoi2008]Cave 洞穴勘测(LCT)

[SDOI2008]Cave 洞穴勘测

[SDOI 2008]Cave 洞穴勘测

BZOJ2049: [Sdoi2008]Cave 洞穴勘测 LCT模板