zoukankan      html  css  js  c++  java
  • luogu3690 【模板】Link Cut Tree (动态树)

    题目

    luogu3690

    硫硼作者想提醒大家,WA 了 TLE 了 RE 了的,也许只是主函数写错了

    image

    代码

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    
    #define pa T[x].fa
    #define l T[x].ch[0]
    #define r T[x].ch[1]
    const int N=300005;
    
    struct lct
    {
        struct node
        {
            int ch[2],fa,sum,rev,w;//sum记录以当前节点为根的辅助树的权值和 
        }T[N];
        bool son(int x){return T[pa].ch[1]==x;}//判断是否为右儿子 
        bool isroot(int x){return T[pa].ch[0]!=x&&T[pa].ch[1]!=x;}//判断节点x是否为所处辅助树的根
        //每个辅助树之间是有连接的,即儿子都认父亲,父亲只认重儿子,所以当其父亲左右儿子都不为自己时,当前节点为所处辅助树的根 
        void reverse(int x){T[x].rev^=1;swap(l,r);}//翻转
        void update(int x){T[x].sum=T[l].sum^T[r].sum^T[x].w;}//异或 
        void pushdown_once(int x)//下传翻转标记 
        {
            if(!T[x].rev) return;
            if(l) reverse(l); if(r) reverse(r);
            T[x].rev=0;
        }
        void pushdown(int x){if(!isroot(x)) pushdown(pa);pushdown_once(x);}//从上往下翻转 
        void lk(int x,int y,int f)
        {
            T[x].ch[f]=y;
            T[y].fa=x;
        }
        void rotate(int x)
        {
            int y=T[x].fa,z=T[y].fa,f=son(x);
            if(!isroot(y)) T[z].ch[son(y)]=x;T[x].fa=z;//如果是根,儿子认父亲,父亲不认儿子 
            T[y].ch[f]=T[x].ch[f^1];T[T[x].ch[f^1]].fa=y; 
            T[x].ch[f^1]=y;T[y].fa=x;
            update(y);update(x);
        }  
        void splay(int x)//将x转至根 
        {
            pushdown(x);
            while(!isroot(x))
            {
                if(!isroot(pa)) rotate(son(pa)==son(x)? pa:x);
                rotate(x);
            }
        }
        /***/
        void access(int x){for(int y=0;x;y=x,x=pa) splay(x),r=y,update(x);}//将当前节点至根的路径修改为一条重链
        void makeroot(int x){access(x);splay(x);reverse(x);}//将x换为原树的根 
        int findroot(int x)//查询节点x所在树的根 
        {
            access(x);splay(x);
            while(l) pushdown_once(x),x=l;return x;
        }
        void link(int x,int y){makeroot(x);T[x].fa=y;}//将x接在y下方(反着接也可以)
        void cut(int x,int y)//断开x,y的连接 
        {
            makeroot(x);access(y);splay(y);
            T[x].fa=T[y].ch[0]=0;update(y);
        }
        void split(int x,int y){makeroot(x);access(y);splay(y);}
    }st;
    
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&st.T[i].w);
        for(int i=1;i<=m;i++)
        {
            int opt,x,y;scanf("%d%d%d",&opt,&x,&y);
            if(opt==0) st.split(x,y),printf("%d
    ",st.T[y].sum);
            if(opt==1) if (st.findroot(x)!=st.findroot(y)) st.link(x,y);
            if(opt==2) if (st.findroot(x)==st.findroot(y)) st.cut(x,y);
            if(opt==3) st.T[x].w=y,st.splay(x);
        }
        return 0;
    }
  • 相关阅读:
    Backbone Events 源码笔记
    IIS8集成模式下打开静态资源被aspx处理程序处理,StaticFileModule失效问题分析
    Orchard 与 ABP架构比较 (aspnetboilerplate)
    Orchard EventBus 事件总线及 IEventHandler作用
    Orchard 事件通知小坑
    推荐一个国内编程语言排名网站
    po_文件格式[转]
    关于poedit打开po文件乱码的问题
    JAVA和.NET工作流相关项目收集
    php里的二进制安全
  • 原文地址:https://www.cnblogs.com/XYZinc/p/7857200.html
Copyright © 2011-2022 走看看