zoukankan      html  css  js  c++  java
  • QTREE6&&7

    树上连通块

    不用具体距离,只询问连通块大小或者最大权值

    可以类比Qtree5的方法,但是记录东西很多,例如子树有无0/1颜色等

    一个trick,两个LCT分离颜色

    每个颜色在边上。

    仅保留连通块顶部不是相同颜色,使得断边不会被菊花图卡掉

    所以内部颜色不用考虑了,专心维护子树值。

    查询时候findrt,splay,右儿子即可。

    Qtree6

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    
    namespace Miracle{
    const int N=1000000+5;
    int n,m;
    int f[N];
    int co[N];
    struct LCT{
        #define ls ch[x][0]
        #define rs ch[x][1]
        int fa[N],ch[N][2];
        int sz[N],si[N];
        bool nrt(int x){
            return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
        }
        void pushup(int x){
            if(x)
            sz[x]=si[x]+sz[ls]+sz[rs]+1;
        }
        void rotate(int x){
            int y=fa[x],d=ch[y][1]==x;
            fa[ch[y][d]=ch[x][!d]]=y;
            if(nrt(y)) ch[fa[x]=fa[y]][ch[fa[y]][1]==y]=x;
            else fa[x]=fa[y];
            fa[ch[x][!d]=y]=x;
            pushup(y);
        }
        void splay(int x){
            while(nrt(x)){
                int y=fa[x],z=fa[y];
                if(nrt(y)){
                    rotate((ch[y][0]==x)==(ch[z][0]==y)?y:x);
                }
                rotate(x);
            }
            pushup(x);
        }
        void access(int x){
            for(reg y=0;x;y=x,x=fa[x]){
                //cout<<" xx "<<x<<endl;
                splay(x);si[x]-=sz[y];si[x]+=sz[ch[x][1]];
                ch[x][1]=y;
                pushup(x);
            }
        }
        int findrt(int x){
            access(x);splay(x);
            while(ch[x][0]) x=ch[x][0];
            splay(x);
            return x;
        }
        void link(int x){
            //cout<<" link "<<x<<endl;
            splay(x);
            int y=fa[x]=f[x];
            access(y);splay(y);
            si[y]+=sz[x];
            pushup(y);
        }
        void cut(int x){
        //    cout<<" cut "<<x<<endl;
            access(x);splay(x);
        //    cout<<ls<<" "<<ch[x][0]<<endl;
            ls=fa[ls]=0;
            pushup(x);
        }
        int query(int x){
            int lp=findrt(x);
        //    cout<<" lp "<<lp<<" "<<sz[lp]<<" "<<si[lp]<<endl;
            return sz[lp]-si[lp]-1;
        }
    }lct[2];
    vector<int>to[N];
    void dfs(int x){
        for(reg i=0;i<(int)to[x].size();++i){
            if(to[x][i]!=f[x]){
                f[to[x][i]]=x;dfs(to[x][i]);
                lct[1].link(to[x][i]);
            }
        }
    }
    int main(){
        rd(n);
        int x,y;
        for(reg i=1;i<n;++i)rd(x),rd(y),to[x].push_back(y),to[y].push_back(x);
        for(reg i=1;i<=n+1;++i) lct[0].sz[i]=1,lct[1].sz[i]=1,co[i]=1;
        to[n+1].push_back(1);
        dfs(n+1);
        int op;
        rd(m);
        while(m--){
            rd(op);rd(x);
            if(!op){
                printf("%d
    ",lct[co[x]].query(x));
            }else{
                lct[co[x]].cut(x);
            //    cout<<" after co[x] cut "<<endl;
                lct[co[x]^1].link(x);
                co[x]^=1;
            }
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/3/15 10:57:40
    */
    View Code

    Qtree7

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    
    namespace Miracle{
    const int N=1e5+5;
    const int inf=0x3f3f3f3f;
    int n,m;
    int fa[N];
    struct LCT{
        struct node{
            int ch[2],fa;
            int val;
            int ans;
            priority_queue<int>q,d;
            void dele(int c){
                d.push(c);
            }
            void ins(int c){
                q.push(c);
            }
            int top(){
                while(!q.empty()&&!d.empty()&&q.top()==d.top()) q.pop(),d.pop();
                if(!q.empty()) return q.top();
                return -inf;
            }
        }t[N];
        bool nrt(int x){
            return t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x;
        }
        void pushup(int x){
            t[x].ans=max(t[x].val,max(t[x].top(),max(t[t[x].ch[0]].ans,t[t[x].ch[1]].ans)));
        }
        void rotate(int x){
            int y=t[x].fa,d=t[y].ch[1]==x;
            t[t[y].ch[d]=t[x].ch[!d]].fa=y;
            if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x;
            else t[x].fa=t[y].fa;
            t[t[x].ch[!d]=y].fa=x;
            pushup(y);
        }
        void splay(int x){
            while(nrt(x)){
                int y=t[x].fa,z=t[y].fa;
                if(nrt(y)){
                    rotate((t[y].ch[1]==x)==(t[z].ch[1]==y)?y:x);
                }rotate(x);
            }
            pushup(x);
        }
        void access(int x){
            for(reg y=0;x;y=x,x=t[x].fa){
                splay(x);t[x].dele(t[y].ans);
                t[x].ins(t[t[x].ch[1]].ans);
                t[x].ch[1]=y;
                pushup(x);
            }
        }
        int findrt(int x){
            access(x);splay(x);
            while(t[x].ch[0]) x=t[x].ch[0];
            splay(x);
            return x;
        }
        void link(int x){
        //    cout<<" link "<<x<<" t.fa "<<t[x].fa<<" fa "<<fa[x]<<" ans "<<t[x].ans<<" val "<<t[x].val<<endl;
            splay(x);
            int y=t[x].fa=fa[x];
            access(y);splay(y);
            t[y].ins(t[x].ans);
            pushup(y);
        }
        void cut(int x){
            access(x);splay(x);
            t[x].ch[0]=t[t[x].ch[0]].fa=0;
            pushup(x);
        }
        void chan(int x,int c){//chan val
            access(x);splay(x);
            t[x].val=c;
            pushup(x);
        }
        int query(int x){
            int lp=findrt(x);
            return t[t[lp].ch[1]].ans;
        }
    }lct[2];
    vector<int>to[N];
    int co[N],wei[N];
    void dfs(int x){
        //cout<<x<<endl;
        for(reg i=0;i<(int)to[x].size();++i){
            int y=to[x][i];
            if(y==fa[x]) continue;
            fa[y]=x;
            dfs(y);
            lct[co[y]].link(y);
        }
    }
    int main(){
    
        rd(n);
        lct[0].t[0].ans=lct[0].t[0].val=-inf;
        lct[1].t[0].ans=lct[1].t[0].val=-inf;
        lct[0].t[n+1].ans=lct[0].t[n+1].val=-inf;
        lct[1].t[n+1].ans=lct[1].t[n+1].val=-inf;
        int x,y;
        for(reg i=1;i<n;++i){
            rd(x);rd(y);
            to[x].push_back(y);to[y].push_back(x);
        }
        to[n+1].push_back(1);
        for(reg i=1;i<=n;++i){
            rd(co[i]);
        }
        for(reg i=1;i<=n;++i){
            rd(wei[i]);
        //    cout<<" i "<<i<<" "<<wei[i]<<endl;
            lct[0].t[i].val=lct[0].t[i].ans=wei[i];
            lct[1].t[i].val=lct[1].t[i].ans=wei[i];
        }
        wei[n+1]=-inf;
        dfs(n+1);
        
        rd(m);int op;
        while(m--){
            rd(op);rd(x);
            if(op==0){
                printf("%d
    ",lct[co[x]].query(x));
            }else if(op==1){
                lct[co[x]].cut(x);lct[co[x]^1].link(x);
                co[x]^=1;
            }else{
                rd(y);
                lct[0].chan(x,y);
                lct[1].chan(x,y);
            }
        }
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/3/15 14:12:29
    */
    View Code
  • 相关阅读:
    leetcode 7:binary-tree-preorder-traversal
    leetcode 49:same-tree
    leetcode 45:maximum-depth-of-binary-tree
    leetcode 15:single number
    leetcode开始刷题!
    MFC按行读写文件,亲测有用!
    把字符串转换成整数
    数组中重复的数字
    CSS盒子模型图
    HTML5入门:HTML5的文档声明和基本代码
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10537086.html
Copyright © 2011-2022 走看看