• Link cut tree


    https://www.luogu.org/problem/P3690

    知识点:

    #include <bits/stdc++.h>
    using namespace std;
    int n,m;
    struct node
    {
        int fa;
        int ch[2];
        int sum;
        int val;
        int lazy;
    }t[310000];
    bool root(int x)
    {
        int g = t[x].fa;
        return !((t[g].ch[0] == x)||(t[g].ch[1] == x));
    }
    void pushup(int x)
    {
        int l = t[x].ch[0],r = t[x].ch[1];
        t[x].sum = t[x].val ^ t[l].sum ^ t[r].sum;
    }
    inline void pushr(int x)
    {
        if(!x)return;
        swap(t[x].ch[0],t[x].ch[1]);
        t[x].lazy ^= 1;
    }
    void pushdown(int x)
    {
        if(t[x].lazy)
        {
            pushr(t[x].ch[0]);
            pushr(t[x].ch[1]);
            t[x].lazy = 0;
        }
    }
    void push(int x)
    {
        if(!root(x))push(t[x].fa);
        pushdown(x);
    }
    void rotate(int x)
    {
        int y = t[x].fa;
        int z = t[y].fa;
        int k = t[y].ch[1] == x;
        if(!root(y)) t[z].ch[t[z].ch[1] == y] = x; 
        t[x].fa = z;
        t[y].ch[k] = t[x].ch[k ^ 1];
        if(t[x].ch[k ^ 1])t[t[x].ch[k ^ 1]].fa = y;
        t[y].fa = x;
        t[x].ch[k ^ 1] = y;
        pushup(y);pushup(x);
    }
    void splay(int x)
    {
        int y,z;
        push(x);
        while(!root(x))
        {
            y = t[x].fa,z = t[y].fa;
            if(!root(y))
            {
                (t[z].ch[0] == y) ^ (t[y].ch[0] == x)?rotate(x):rotate(y);
            }
            rotate(x);
        }
        pushup(x);
    }
    void access(int x)
    {
        for(int y = 0;x;y = x,x = t[x].fa)
        {
            splay(x);t[x].ch[1] = y;pushup(x);
        }                                   
    }
    void makeroot(int x)
    {
        access(x);splay(x);
        pushr(x);          
    }
    void split(int x,int y)
    {
        makeroot(x);
        access(y);
        splay(y);
    } 
    void link(int x,int y)
    {
        makeroot(x);
        t[x].fa = y;
    }
    void cut(int x,int y)
    {
        makeroot(x);
        access(y);
        splay(y);
        if(t[y].ch[0] != x || t[x].ch[1])return;
        t[x].fa = t[y].ch[0] = 0;
        pushup(x);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&t[i].val);
            t[i].sum = t[i].val;
        }
        int opt,a,b;
        while(m--)
        {
            scanf("%d%d%d",&opt,&a,&b);
            switch(opt)
            {
                case 0:
                {
                    if(a == b)
                    {
                        printf("%d
    ",t[a].val);
                        break;
                    }
                    split(a,b);
                    pushup(b);
                    printf("%d
    ",t[b].sum);
                    break;
                }
                case 1:
                {
                    link(a,b);
                    break;
                }
                case 2:
                {
                    cut(a,b);
                    break;
                }
                case 3:
                {
                    splay(a);
                    t[a].val = b;
                    pushup(a);
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Windows 2008 server + IIS 7 设置身份模拟(ASP.NET impersonation)
    记录windows操作系统启动日志
    C# 重启计算机的问题
    AcWing 1086 恨7不是妻
    AcWing 1084. 数字游戏 II
    AcWing 1083. Windy数
    golang学习笔记 生成JSON及解析JSON 清明
    WEB前端底层知识之浏览器是如何工作的(2)渲染引擎
    ASP.NET MVC Razor 输出没有编码的HTML字符串
    ext.grid的配置属性和方法
  • 原文地址:https://www.cnblogs.com/xyj1/p/11340638.html
Copyright © 2020-2023  润新知