• UVA 11994 Happy Painting!


    UVA_11994

        这个题目思维上的障碍比较少,因为实际上都是link-cut-tree的基本的操作,还有一个更为复杂的link-cut-tree的题目——HDU_4010

        在维护路径上边的颜色的数量时,由于颜色的种类只有30个,因此可以用一个整数的30个二进制位来存储颜色的种类。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 50010
    int N, M;
    struct Splay
    {
        int pre, ls, rs, col, set, to, size;
        bool root;
        void pushdown(); void update(); void zig(int x); void zag(int x); void splay(int x);
        void init()
        {
            root = true;
            size = to = pre = ls = rs = col = set = 0;
        }
    }sp[MAXD];
    inline void same(int x, int c)
    {
        if(x) sp[x].to = sp[x].col = c, sp[x].set = 1 << c;
    }
    inline void Splay::pushdown()
    {
        if(to)
        {
            same(ls, to), same(rs, to);
            to = 0;
        }
    }
    inline void Splay::update()
    {
        set = sp[ls].set | sp[rs].set | 1 << col;
        size = sp[ls].size + sp[rs].size + 1;
    }
    void Splay::zig(int x)
    {
        int y = rs, fa = pre;
        rs = sp[y].ls, sp[rs].pre = x;
        sp[y].ls = x, pre = y;
        sp[y].pre = fa;
        if(root)
            root = false, sp[y].root = true;
        else
            sp[fa].rs == x ? sp[fa].rs = y : sp[fa].ls = y;
        update();    
    }
    void Splay::zag(int x)
    {
        int y = ls, fa = pre;
        ls = sp[y].rs, sp[ls].pre = x;
        sp[y].rs = x, pre = y;
        sp[y].pre = fa;
        if(root)
            root = false, sp[y].root = true;
        else
            sp[fa].rs == x ? sp[fa].rs = y : sp[fa].ls = y;
        update();
    }
    void Splay::splay(int x)
    {
        int y, z;
        for(pushdown(); !root;)
        {
            y = pre;
            if(sp[y].root) sp[y].pushdown(), pushdown(), sp[y].rs == x ? sp[y].zig(y) : sp[y].zag(y);
            else
            {
                z = sp[y].pre, sp[z].pushdown(), sp[y].pushdown(), pushdown();
                if(sp[z].rs == y)
                {
                    if(sp[y].rs == x) sp[z].zig(z), sp[y].zig(y);
                    else sp[y].zag(y), sp[z].zig(z);
                }
                else
                {
                    if(sp[y].ls == x) sp[z].zag(z), sp[y].zag(y);
                    else sp[y].zig(y), sp[z].zag(z);
                }    
            }
        }
        update();
    }
    void access(int x)
    {
        int fx;
        for(fx = x, x = 0; fx != 0; x = fx, fx = sp[x].pre)
        {
            sp[fx].splay(fx);
            sp[sp[fx].rs].root = true, sp[fx].rs = x, sp[x].root = false;
            sp[fx].update();
        }    
    }
    void cut(int x)
    {
        access(x), sp[x].splay(x);
        sp[sp[x].ls].root = true, sp[sp[x].ls].pre = 0, sp[x].ls = 0;
        sp[x].update();
    }
    void join(int x, int y, int c)
    {
        access(y), sp[y].splay(y);
        sp[x].splay(x);
        if(sp[y].pre != 0) return ;
        cut(x);
        sp[x].pre = y, sp[x].col = c;
        sp[x].update();
    }
    void init()
    {
        int i, x;
        for(i = 1; i <= N; i ++)
        {
            scanf("%d", &x);
            sp[i].init(), sp[i].pre = x;
        }
        for(i = 1; i <= N; i ++)
        {
            scanf("%d", &x);
            sp[i].col = x, sp[i].set = 1 << x, sp[i].size = 1;
        }
        sp[0].init();
    }
    void paint(int x, int y, int c)
    {
        int fx;
        access(y), sp[y].splay(y);
        for(fx = x, x = 0; fx != 0; x = fx, fx = sp[x].pre)
        {
            sp[fx].splay(fx);
            if(sp[fx].pre == 0)
            {
                if(sp[y].pre != 0 || fx == y) same(sp[fx].rs, c), same(x, c);
            }
            sp[sp[fx].rs].root = true, sp[fx].rs = x, sp[x].root = false;
            sp[fx].update();    
        }    
    }
    void count(int x, int y)
    {
        int fx;
        access(y), sp[y].splay(y);
        for(fx = x, x = 0; fx != 0; x = fx, fx = sp[x].pre)
        {
            sp[fx].splay(fx);
            if(sp[fx].pre == 0)
            {
                if(sp[y].pre == 0 && fx != y) printf("0 0\n");
                else
                {
                    int cnt = 0, t = sp[sp[fx].rs].set | sp[x].set;
                    for(int i = 1; i <= 30; i ++) if(t & 1 << i) ++ cnt;
                    printf("%d %d\n", sp[sp[fx].rs].size + sp[x].size, cnt);
                }
            }
            sp[sp[fx].rs].root = true, sp[fx].rs = x, sp[x].root = false;
            sp[fx].update();    
        }    
    }
    void solve()
    {
        int i, op, x, y, c;
        for(i = 0; i < M; i ++)
        {
            scanf("%d", &op);
            if(op == 1)
            {
                scanf("%d%d%d", &x, &y, &c);
                if(x == y) continue;
                join(x, y, c);
            }    
            else if(op == 2)
            {
                scanf("%d%d%d", &x, &y, &c);
                if(x == y) continue;
                paint(x, y, c);    
            }
            else
            {
                scanf("%d%d", &x, &y);
                if(x == y) printf("0 0\n");
                else count(x, y);    
            }
        }
    }
    int main()
    {
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            solve();    
        }
        return 0;    
    }
  • 相关阅读:
    Pandas使用详细教程(个人自我总结版)
    时间序列算法理论及python实现(2-python实现)
    时间序列算法理论及python实现(1-算法理论部分)
    卡方分布、卡方独立性检验和拟合性检验理论及其python实现
    配置环境变量时,cmd下运行java -version,报错:找不到或无法加载主类 -version
    Git 版本管理器学习笔记
    python、数据分析师、算法工程师的学习计划
    脏读、幻读、不可重复读、mvcc
    数据是如何存储在磁盘的
    Mysql之Buffer Pool详解与调优
  • 原文地址:https://www.cnblogs.com/staginner/p/2652982.html
Copyright © 2020-2023  润新知