zoukankan      html  css  js  c++  java
  • [BZOJ 3282] Tree

    [题目链接]

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

    [算法]

            LCT模板题

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

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 300010
    
    int n , m;
    int val[MAXN];
    
    template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
    template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    
    struct Link_Cut_Tree
    {
        struct Node
        {
            int father , son[2];
            int v , value;    
            bool tag;
        } a[MAXN];
        inline bool nroot(int x)
        {
            return a[a[x].father].son[0] == x | a[a[x].father].son[1] == x;
        }
        inline void update(int x)
        {
            a[x].value = a[x].v ^ a[a[x].son[0]].value ^ a[a[x].son[1]].value;
        }
        inline void init()
        {
            for (int i = 1; i <= n; i++)
                a[i].v = val[i];    
        } 
        inline bool get(int x)
        {
            pushdown(a[x].father);
            return a[a[x].father].son[1] == x;
        }
        inline void pushdown(int x)
        {
            if (a[x].tag)
            {
                swap(a[x].son[0] , a[x].son[1]);
                a[a[x].son[0]].tag ^= true;
                a[a[x].son[1]].tag ^= true;
                a[x].tag = false;
            }
        }
        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;
            update(f);
        }
        inline int find_root(int x)
        {
            access(x);
            splay(x);
            while (a[x].son[0])
            {
                pushdown(x);
                x = a[x].son[0];
            }
            return x;
        }
        inline void access(int x)
        {
            for (int y = 0; x; x = a[y = x].father)
            {
                splay(x);
                a[x].son[1] = y;
                update(x);
            }
        }
        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) ? x : y);
                rotate(x);
            }
            update(x);
        }
        inline void split(int x , int y)
        {
            make_root(x);
            access(y);
            splay(y);    
        } 
        inline void make_root(int x)
        {
            access(x);
            splay(x);
            a[x].tag ^= true;
            pushdown(x);
        }
        inline void link(int x , int y)
        {
            make_root(x);
            if (find_root(y) != x) a[x].father = y;
        }
        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;
                update(y);
            }
        }
    } LCT;
    
    int main()
    {
        
        read(n); read(m);
        for (int i = 1; i <= n; i++) read(val[i]);
        LCT.init();
        while (m--)
        {
            int type , x , y;
            read(type); read(x); read(y);
            if (type == 0)
            {
                LCT.split(x , y);
                printf("%d
    " , LCT.a[y].value);    
            } else if (type == 1) LCT.link(x , y);
            else if (type == 2) LCT.cut(x , y);
            else
            {
                LCT.splay(x);
                LCT.a[x].v = y;
            }
        }
        
        return 0;
    }
  • 相关阅读:
    Grid++Report 报表开发工具
    docker(1):virtualbox 安装CoreOS系统,配置registry-mirror
    [Network]Introduction and Basic concepts
    Java进程堆外内存(off heap)大小
    可设置指定时间自己主动消失的 MessageBox实现
    《iOS Human Interface Guidelines》——Wallet
    什么是OpenStack
    Filters.h各种信号恢复滤波器头文件
    Android时间轴效果,直接使用在你的项目中
    浅析C++多重继承
  • 原文地址:https://www.cnblogs.com/evenbao/p/10088925.html
Copyright © 2011-2022 走看看