• [SDOI2011]染色


    题目:染色

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2243

    分析:

    (1)很裸的树链剖分,然而我忘了树剖怎么打(其实是代码太长不想打,逃

    (2)于是挖了一个大坑,把自己埋下去了(全世界是不是只有我傻傻打了LCT?

    (3)卡卡OJ竟然过了,数据太弱了好慌。

    (4)LCT好像没有什么细节(也不知道是谁调了一晚上

    (5)简单说一下变量

     num[x](SplayTree中x所控制的子树中颜色段数量)

     lc[x](SplayTree中x所控制的子树中最左边的点的颜色)

     rc[x](SplayTree中x所控制的子树中最右边的点的颜色)

     vc[x](x点本身的颜色)

     tag[x](lazy_tag标记)

     rev[x](LCT专用翻转标记)

    (6)简单说一下更新操作(Up operation)

     num[x] : num[x]=(IF exist left_tree)num[ls[x][0]]-(rc[ls[x][0]]==vc[x])+(IF exist right_tree)num[ls[x][1]]-(lc[tr]==vc[x])+1;

     lc[x] : IF (exist left_tree) lc[x]=lc[ls[x][0]] ELSE lc[x]=vc[x];

     rc[x] : IF (exist right_tree) rc[x]=rc[ls[x][0]] ELSE rc[x]=vc[x];

    (7)简单说一下下传操作 ( Down operation )

    IF(exist rev operation):

      IF(exist left_tree)rev[ls[x][0]]^=1;

      IF(exist right_tree)rev[ls[x][1]]^=1;

      clear rev[x];

      swap(left_tree,right_tree);

      swap(lc[x],rc[v])(因为左右子树互换,相应最左最右颜色要换

    IF(exist tag operation):

      To intialize rc[x],lc[x],vc[x],num[x];

      IF(exist left_tree)tag[ls[x][0]]=tag[x];

      IF(exist right_tree)tag[ls[x][1]]=tag[x];

      clear tag[x];(tag[x]=-1 becase $color in [0,10^9]$)

    (8)简单说一些其他

      LCT自带log的常数,并且我自带巨大常数,用时是树剖的4倍以上

      不过代码比树剖短1K左右,比较好打

      不过LCT没有用到堆栈,不用担心栈溢出的问题

      yy一下,比如支持连边操作,断边操作等等能够修改树的形态的操作,有没有什么好的做法?

    代码:

    LCT

    #include <cstdio>
    #include <algorithm>
    const int N=100005;
    int n,m;
    struct LinkCutTree{
        int fa[N],ls[N][2];
        int rev[N],num[N],tag[N],lc[N],rc[N],vc[N];
        void Down(int &x){
            int &tl=ls[x][0],&tr=ls[x][1];
            if(rev[x]){
                if(tl)rev[tl]^=1;if(tr)rev[tr]^=1;rev[x]=0;
                std::swap(tl,tr);std::swap(lc[x],rc[x]);
            }
            if(tag[x]!=-1){
                lc[x]=rc[x]=vc[x]=tag[x];num[x]=1;
                if(tl)tag[tl]=tag[x];if(tr)tag[tr]=tag[x];tag[x]=-1;
            }
        }
        void Up(int &x){
            int &tl=ls[x][0],&tr=ls[x][1];
            if(rev[tl] || tag[tl]!=-1)Down(tl);
            if(rev[tr] || tag[tr]!=-1)Down(tr);
            if(tl)lc[x]=lc[tl];else lc[x]=vc[x];
            if(tr)rc[x]=rc[tr];else rc[x]=vc[x];
            num[x]=num[tl]+num[tr]+1;
            if(tl&&rc[tl]==vc[x])--num[x];
            if(tr&&lc[tr]==vc[x])--num[x];
        }
        bool IsRoot(int x){return ls[fa[x]][0]==x || ls[fa[x]][1]==x;} 
        void Rotate(int x){
            int y=fa[x],z=fa[y],s=ls[y][1]==x;
            if(IsRoot(y))ls[z][ls[z][1]==y]=x;fa[x]=z;
            fa[ls[y][s]=ls[x][s^1]]=y;
            fa[ls[x][s^1]=y]=x;
            Up(y);Up(x);
        }
        void Pr(int x){if(IsRoot(x))Pr(fa[x]);Down(x);}
        void Splay(int x){
            Pr(x);
            for(int y;IsRoot(x);Rotate(x))
                if(IsRoot(y=fa[x]))
                    if((x==ls[y][0])^(y==ls[fa[y]][0]))
                        Rotate(x);else Rotate(y);
        }
        void Access(int x){
            for(int y=0;x;x=fa[y=x]){
                Splay(x);Up(fa[ls[x][1]=y]=x);
            }
        }
        void Markroot(int x){Access(x);Splay(x);rev[x]^=1;}
        void Link(int x,int y){Markroot(x);Markroot(y);fa[y]=x;}
        void Split(int x,int y){Markroot(x);Access(y);Splay(y);}
    }T;
    int Read(){
        int ch='@',t=0;
        for(;ch<48 || 57<ch;ch=getchar());
        for(;47<ch && ch<58;ch=getchar())t=t*10+ch-48;
        return t;
    }
    int main(){
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        n=Read();m=Read();T.tag[0]=-1;
        for(int i=1;i<=n;++i){
            T.lc[i]=T.rc[i]=T.vc[i]=Read();
            T.num[i]=1;T.tag[i]=-1;
        }
        for(int i=1,a,b;i<n;++i){
            a=Read();b=Read();T.Link(a,b);
        }
        char op;
        for(int i=1,a,b,c;i<=m;++i){    
            scanf("
    %c",&op);a=Read();b=Read();
            if(op=='C'){
                c=Read();T.Split(a,b);T.tag[b]=c;
            }else{
                T.Split(a,b);printf("%d
    ",T.num[b]);
            }
        }
        //fclose(stdin);fclose(stdout);
        return 0;
    }
  • 相关阅读:
    车载OS盘点及特点分析一:车载OS几大系统介绍
    CTF常用软件/工具
    汽车软件产业研究报告(2020年)
    高级加密标准(AES)分析
    工具 | CTP、SimNow、NSight、快期
    CTF之图片隐写术解题思路
    V2X和车路协同研究:5G V2X将成为数字座舱标配
    腾讯安全正式发布《IoT安全能力图谱》
    Microsoft Remote Desktop Beta 下载地址
    密码学初探|加密模式
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/6725847.html
Copyright © 2020-2023  润新知