zoukankan      html  css  js  c++  java
  • [SDOI2008] 洞穴勘测

    题目链接:戳我
    LCT维护连通性类型的题目,主要是要搞清楚findroot函数的作用——判断根是否相同,和并查集里面的find()函数有异曲同工之妙,如果根相同可以认为两个点具有连通性。
    先access打通一道到x的实边,现在x是深度最大的节点。然后再splay x到根节点,因为它深度最大,这个时候它只有左子树。所以找它的原树的根就去左节点找好啦qwq。(原树节点是中序遍历深度最小的嘛)
    哦 对了,因为找根的时候有可能标记没有完全释放掉。。。最好还是push_down一下吧。。。原先没有注意到,看了flash_hu dalao的博客才注意到。。。qwqwq
    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 100010
    #define mod 51061
    using namespace std;
    int n,m,tot;
    int s[MAXN];
    struct Node{int val,rev,son,sum,ff,ch[2];}t[MAXN];
    inline void push_up(int x)
    {
        t[x].sum=(t[t[x].ch[0]].sum+t[t[x].ch[1]].sum+t[x].val)%mod;
        t[x].son=t[t[x].ch[0]].son+t[t[x].ch[1]].son+1;
    }
    inline bool isroot(int x){return t[t[x].ff].ch[0]!=x&&t[t[x].ff].ch[1]!=x;}
    inline void rotate(int x)
    {
        int y=t[x].ff;
        int z=t[y].ff;
        int k=t[y].ch[1]==x;
        if(!isroot(y)) t[z].ch[t[z].ch[1]==y]=x; t[x].ff=z;
        t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y;
        t[x].ch[k^1]=y; t[y].ff=x;
        push_up(y),push_up(x);
    }
    inline void push_down(int x)
    {
        if(t[x].rev)
        {
            if(t[x].ch[0]) t[t[x].ch[0]].rev^=1;
            if(t[x].ch[1]) t[t[x].ch[1]].rev^=1;
            swap(t[x].ch[0],t[x].ch[1]);
            t[x].rev^=1;
        }
    }
    inline void splay(int x)
    {
        s[tot=1]=x;
        for(int i=x;!isroot(i);i=t[i].ff) s[++tot]=t[i].ff;
        while(tot) push_down(s[tot--]);
        while(!isroot(x))
        {
            int y=t[x].ff;
            int z=t[y].ff;
            if(!isroot(y))
                ((t[y].ch[0]==x)^(t[z].ch[0]==y))?rotate(x):rotate(y);
            rotate(x);
        }
    }
    inline void access(int x)
    {
        for(int y=0;x;y=x,x=t[x].ff)
            splay(x),t[x].ch[1]=y,push_up(x);
    }
    inline void makeroot(int x){access(x);splay(x);t[x].rev^=1;}
    inline void split(int x,int y){makeroot(x);access(y);splay(y);}
    inline void cut(int x,int y){split(x,y);t[y].ch[0]=t[x].ff=0;push_up(y);}
    inline void link(int x,int y){makeroot(x);t[x].ff=y;}
    inline int findroot(int x)
    {   
        access(x);
        splay(x);
        while(t[x].ch[0]) push_down(x),x=t[x].ch[0];
        return x;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) t[i].son=t[i].val=1;
        for(int i=1;i<=m;i++)
        {
            char cur[10];
            int u,v;
            scanf("%s",cur);
            scanf("%d%d",&u,&v);
            if(cur[0]=='Q')
            {
                if(findroot(u)==findroot(v)) printf("Yes
    ");
                else printf("No
    ");
            }
            else if(cur[0]=='D') cut(u,v);
            else link(u,v);
        }
        return 0;
    } 
    
  • 相关阅读:
    小米9一直无限重启是怎么办
    发现一个大神做了一个ROS-ROUTEROS的中文手册中文使用说明书
    浅谈CN2 GIA和CN2 GT线路的区别
    本地ROS多线访问同一个服务器的IP,比如阿里云的IP,创建冗余线路
    syslog之三:建立Windows下面的syslog日志服务器
    增值税专用发票“抵扣联”和“发票联”丢失怎么办
    在线播放 4K 内容的需要多少带宽?
    戴尔R640服务器用H740P配置阵列
    搞微服务用阿里开源的 Nacos 真香啊!
    保持ssh不自动断开
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10285887.html
Copyright © 2011-2022 走看看