[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\n" , 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;
}

 

posted @ 2018-12-08 20:20  evenbao  阅读(143)  评论(0编辑  收藏  举报