zoukankan      html  css  js  c++  java
  • HYSBZ 2243 染色 LCT学习

    这道题感觉非常简单,(其实用树链剖分写的话肯定快多了),一个区间染色问题,需要记录一下最左段,最右端的颜色,还有就是有几段,这样才能维护起来,在一个傻逼地方wa了好多遍,翻转的时候,左端的颜色变成了右端的颜色,右端的颜色变成了左端的颜色。下面是代码:

    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #define LL long long
    #define INF 0x3fffffff
    #define FOR(i,x,y)  for(int i = x;i < y;i ++)
    #define IFOR(i,x,y) for(int i = x;i > y;i --)
    #define MAXN 110000
    
    using namespace std;
    
    int n,m;
    vector <int> mat[MAXN];
    
    struct LCT{
        int pre[MAXN],ch[MAXN][2],key[MAXN],flip[MAXN];
        int ans[MAXN],l[MAXN],r[MAXN],lazy[MAXN];
        bool rt[MAXN];
    
        void Update_Lazy(int x,int w){
            if(!x)  return;
            lazy[x] = w;
            key[x] = w;
            l[x] = w;
            r[x] = w;
            ans[x] = 1;
        }
    
        void Update_Flip(int x){
            if(!x)  return;
            swap(l[x],r[x]);
            swap(ch[x][0],ch[x][1]);
            flip[x] ^= 1;
        }
    
        void Init(){
            memset(ch,0,sizeof(ch));
            memset(flip,0,sizeof(flip));
            memset(rt,true,sizeof(rt));
            FOR(i,1,n+1){
                l[i] = r[i] = key[i];
                ans[i] = 1;
                lazy[i] = -1;
            }
        }
    
        void PushUp(int x){
            ans[x] = 1; l[x] = r[x] = key[x];
            if(ch[x][0]){
                ans[x] += ans[ch[x][0]];
                if(r[ch[x][0]] == key[x])   ans[x] --;
                l[x] = l[ch[x][0]];
            }
            if(ch[x][1]){
                ans[x] += ans[ch[x][1]];
                if(l[ch[x][1]] == key[x])   ans[x] --;
                r[x] = r[ch[x][1]];
            }
        }
    
        void PushDown(int x){
            if(lazy[x] != -1){
                Update_Lazy(ch[x][0],lazy[x]);
                Update_Lazy(ch[x][1],lazy[x]);
                lazy[x] = -1;
            }
            if(flip[x]){
                Update_Flip(ch[x][0]);
                Update_Flip(ch[x][1]);
                flip[x] = 0;
            }
        }
    
        void Rotate(int x,int kind){
            int y = pre[x];
            PushDown(y);
            PushDown(x);
            ch[y][!kind] = ch[x][kind];
            if(ch[x][kind]) pre[ch[x][kind]] = y;
            if(rt[y]){
                rt[x] = true;
                rt[y] = false;
            }
            else{
                if(ch[pre[y]][1] == y)  ch[pre[y]][1] = x;
                if(ch[pre[y]][0] == y)  ch[pre[y]][0] = x;
            }
            pre[x] = pre[y];
            pre[y] = x;
            ch[x][kind] = y;
            PushUp(y);
        }
    
        void Splay(int x){
            PushDown(x);
            while(!rt[x]){
                int y = pre[x];
                int z = pre[y];
                if(rt[y]){
                    PushDown(y); PushDown(x);
                    Rotate(x,ch[y][0] == x);
                }
                else{
                    PushDown(z); PushDown(y); PushDown(x);
                    int kind = ch[z][0] == y;
                    if(ch[y][kind] == x){
                        Rotate(x,!kind);
                        Rotate(x,kind);
                    }
                    else{
                        Rotate(y,kind);
                        Rotate(x,kind);
                    }
                }
            }
            PushUp(x);
        }
    
        void Access(int x){
            int fa = 0;
            for(;x;x = pre[fa = x]){
                Splay(x);
                rt[ch[x][1]] = true;
                rt[ch[x][1] = fa] = false;
                PushUp(x);
            }
        }
    
        int GetRoot(int x){
            Access(x);
            Splay(x);
            while(ch[x][0]) x = ch[x][0];
            return x;
        }
    
        void MakeRoot(int x){
            Access(x);
            Splay(x);
            Update_Flip(x);
        }
    
        void Modify(int u,int v,int w){
            MakeRoot(u);
            Access(v);
            Splay(v);
            Update_Lazy(v,w);
        }
    
        int Query(int u,int v){
            MakeRoot(u);
            Access(v);
            Splay(v);
            return ans[v];
        }
    
    }lct;
    
    void dfs(int u,int fa){
        lct.pre[u] = fa;
        for(int i = 0;i < mat[u].size();i ++){
            int v = mat[u][i];
            if(v == fa) continue;
            dfs(v,u);
        }
    }
    
    int main(){
        //freopen("test.in","r",stdin);
        while(~scanf("%d%d",&n,&m)){
            FOR(i,1,n+1)    mat[i].clear();
            FOR(i,1,n+1)    scanf("%d",&lct.key[i]);
            FOR(i,1,n){
                int u,v;
                scanf("%d%d",&u,&v);
                mat[u].push_back(v);
                mat[v].push_back(u);
            }
            dfs(1,0);
            lct.Init();
            char op[10];
            FOR(i,0,m){
                scanf("%s",op);
                if(op[0] == 'Q'){
                    int u,v;
                    scanf("%d%d",&u,&v);
                    printf("%d
    ",lct.Query(u,v));
                }
                else{
                    int u,v,w;
                    scanf("%d%d%d",&u,&v,&w);
                    lct.Modify(u,v,w);
                }
            }
        }
        return 0;
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Apple Mac OS X每日一技巧002:如何修改打开文档的默认程序
    Baby听世界03:这就是电影啊??!!
    八卦一下,51JOB人才库搜索上海地区含有.NET关键字的期望收入和对应的人数
    接口和抽象类的区别
    总结virtual override sealed new在方法上的应用
    JQuery学习笔记01JQuery初接触
    《C#妹妹和ObjectiveC阿姨对话录》(03)NSString--再遇狗狗
    Mac新手常见问题
    Baby听世界01:产检
    Apple Mac OS X每日一技巧001:如何添加删除开机启动程序项
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4811878.html
Copyright © 2011-2022 走看看