zoukankan      html  css  js  c++  java
  • [模板][P3690]Link Cut Tree

    Description:

    给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。

    0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。

    1:后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接。

    2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。

    3:后接两个整数(x,y),代表将点x上的权值变成y。

    模板,不解释,详见代码

    #include<bits/stdc++.h>
    using namespace std;
    const int mxn=3e5+5;
    int n,m,t[mxn],fa[mxn],st[mxn],rev[mxn],val[mxn],ch[mxn][2];
    
    namespace lct {
        int isnotrt(int x) {
            return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
        };
        void push_up(int x) {
            t[x]=t[ch[x][0]]^t[ch[x][1]]^val[x];
        };
        void push_down(int x) {
            if(rev[x]) {
                rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
                swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
                swap(ch[ch[x][1]][0],ch[ch[x][1]][1]); 
                rev[x]=0;
            }
        }
        void rotate(int x) {
            int y=fa[x],z=fa[y],tp=ch[y][1]==x;
            if(isnotrt(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; //切记要判根
            ch[y][tp]=ch[x][tp^1],fa[ch[x][tp^1]]=y;
            ch[x][tp^1]=y,fa[y]=x;
            push_up(y),push_up(x);
        };
        void splay(int x) {
            int tp=x,s=0; st[++s]=tp;
            while(isnotrt(tp)) st[++s]=tp=fa[tp]; //先下放标记,再splay
            while(s) push_down(st[s--]);
            while(isnotrt(x)) {
                int y=fa[x],z=fa[y];
                if(isnotrt(y))  
                    (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
                rotate(x);	
            }
        };
        void access(int x) {
            for(int y=0;x;x=fa[y=x])
                splay(x),ch[x][1]=y,push_up(x); //要push_up
        };
        void makert(int x) {
            access(x); splay(x); 
            swap(ch[x][0],ch[x][1]);
            rev[x]^=1;
        };
        int findrt(int x) {
            access(x); splay(x);
            while(ch[x][0]) push_down(x),x=ch[x][0]; //要push_down
            splay(x); return x;
        };
        void split(int x,int y) {
            makert(x); access(y); splay(y);
        };
        void link(int x,int y) {
            makert(x); 
            if(findrt(y)!=x) fa[x]=y; //这里需要根据题意写合并条件
        };
        void cut(int x,int y) {
            makert(x);
            if(findrt(y)==x&&fa[y]==x&&!ch[y][0]) { //findrt()之后x成为根,在此基础上分类讨论
                fa[y]=ch[x][1]=0;
                push_up(x);
            }
        };
    }
    using namespace lct;
    
    int main()
    {
        scanf("%d%d",&n,&m); int opt,x,y;
        for(int i=1;i<=n;++i) scanf("%d",val+i);
        while(m--) {
            scanf("%d%d%d",&opt,&x,&y);
            if(opt==0) split(x,y),printf("%d
    ",t[y]);
            else if(opt==1) link(x,y);
            else if(opt==2) cut(x,y);
            else splay(x),val[x]=y;
        }
        return 0;
    }
    
  • 相关阅读:
    SQLServerframework启动报异常:Module的类型初始值设定项引发异常
    在coding或者github建立个人站点域名绑定
    Github速度慢的解决方法
    jsoup爬取网站图片
    activeMQ类别和流程
    Session session = connection.createSession(paramA,paramB);参数解析
    Ehcache入门经典:第二篇ehcache.xml的参数
    Ehcache入门经典:第一篇
    处理高并发
    扩充次数和创建个数问题
  • 原文地址:https://www.cnblogs.com/list1/p/10375845.html
Copyright © 2011-2022 走看看