zoukankan      html  css  js  c++  java
  • BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树

    同BZOJ3779。

    SDOI出原题,还是弱化版的。

    吃枣药丸

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define ll long long
    #define mp make_pair
    #define maxn 200005
     
    int n,m,data[maxn];
     
    namespace Tree{
        int h[maxn],to[maxn],ne[maxn],f[maxn][21],en=0,dep[maxn];
        int id[maxn],in[maxn],out[maxn],tot=0;
        void add(int a,int b)
        {to[en]=b;ne[en]=h[a];h[a]=en++;}
        void dfs(int o)
        {
            in[o]=++tot; id[tot]=o;
            for (int i=h[o];i>=0;i=ne[i])
                if (to[i]!=f[o][0])
                f[to[i]][0]=o,dep[to[i]]=dep[o]+1,dfs(to[i]);
            out[o]=tot;
        }
        void init()
        {
            F(i,1,20)F(j,1,n)f[j][i]=f[f[j][i-1]][i-1];
            F(i,1,n) data[in[i]]=dep[i];
    //      F(i,1,n) printf("%d ",id[i]); printf("
    ");
    //      F(i,1,n) printf("%d ",data[i]);printf("
    ");
        }
        int LCA(int a,int b)
        {
            if (dep[a]<dep[b]) swap(a,b);
            int dist=dep[a]-dep[b];
            D(i,20,0) if ((dist>>i)&1) a=f[a][i];
            if (a==b) return a;
            D(i,20,0) if (f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
            return f[b][0];
        }
    }
     
    namespace SegTree{
        int mx[maxn<<3],tag[maxn<<3];
        void update(int o)
        {mx[o]=max(mx[o<<1],mx[o<<1|1]);}
        void pushdown(int o)
        {
            if (tag[o]!=0)
            {
                tag[o<<1]+=tag[o];
                tag[o<<1|1]+=tag[o];
                mx[o<<1]+=tag[o];
                mx[o<<1|1]+=tag[o];
                tag[o]=0;
            }
        }
        void build(int o,int l,int r)
        {
            if (l==r)
            {
                mx[o]=data[l];
                tag[o]=0;
                return ;
            }
            pushdown(o);
            int mid=l+r>>1;
            build(o<<1,l,mid);
            build(o<<1|1,mid+1,r);
            update(o);
        }
        void modify(int o,int l,int r,int L,int R,int f)
        {
            if (L<=l&&r<=R)
            {
                tag[o]+=f;
                mx[o]+=f;
                return;
            }
            pushdown(o);
            int mid=l+r>>1;
            if (R<=mid) return modify(o<<1,l,mid,L,R,f),update(o);
            else if (L>mid) return modify(o<<1|1,mid+1,r,L,R,f),update(o);
            else return modify(o<<1,l,mid,L,R,f),modify(o<<1|1,mid+1,r,L,R,f),update(o);
        }
        void add(int a,int f)
        {if (!a) return ;modify(1,1,n,Tree::in[a],Tree::out[a],f);}
        int querymx(int o,int l,int r,int L,int R)
        {
            if (L<=l&&r<=R) return mx[o];
            pushdown(o);
            int mid=l+r>>1;
            if (R<=mid) return querymx(o<<1,l,mid,L,R);
            else if (L>mid) return querymx(o<<1|1,mid+1,r,L,R);
            else return max(querymx(o<<1,l,mid,L,R),querymx(o<<1|1,mid+1,r,L,R));
        }
    }
     
    namespace LCT{
        int rev[maxn],fa[maxn],ch[maxn][2],sta[maxn],top=0;
        bool isroot(int o)
        {return ch[fa[o]][0]!=o&&ch[fa[o]][1]!=o;}
        void rot(int x)
        {
            int y=fa[x],z=fa[y],l,r;
            if (ch[y][0]==x) l=0; else l=1; r=l^1;
            if (!isroot(y))
            {
                if (ch[z][0]==y) ch[z][0]=x;
                else ch[z][1]=x;
            }
            fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
            ch[y][l]=ch[x][r]; ch[x][r]=y;
        }
        void pushdown(int x)
        {
            if (rev[x])
            {
                rev[x]^=1;
                rev[ch[x][0]]^=1;
                rev[ch[x][1]]^=1;
                swap(ch[x][0],ch[x][1]);
            }
        }
        void splay(int x)
        {
            sta[top=1]=x;
            for (int i=x;!isroot(i);i=fa[i]) sta[++top]=fa[i];
            while(top) pushdown(sta[top--]);
             
            while (!isroot(x))
            {
                int y=fa[x];
                if (!isroot(y))
                {
                    int z=fa[y];
                    if (ch[z][0]==y^ch[y][0]==x) rot(x);
                    else rot(y);
                }
                rot(x);
            }
        }
        int find(int x)
        {
            pushdown(x);
            while (ch[x][0]) x=ch[x][0],pushdown(x);
            return x;
        }
        void access(int x)
        {
            for (int t=0;x;t=x,x=fa[x])
            {
                splay(x);
                SegTree::add(find(ch[x][1]),1);
                ch[x][1]=t;
                SegTree::add(find(ch[x][1]),-1);
            }
        }
    }
     
    int opt,x,y;
     
    int main()
    {
        scanf("%d%d",&n,&m);
        memset(Tree::h,-1,sizeof Tree::h);
        F(i,2,n)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            Tree::add(a,b);
            Tree::add(b,a);
        }
        Tree::dep[1]=1;Tree::dfs(1);Tree::init();
        F(i,1,n) LCT::fa[i]=Tree::f[i][0];
        SegTree::build(1,1,n);
        F(i,1,m)
        {
            scanf("%d",&opt);
    //      cout<<opt<<endl;
            switch(opt)
            {
                case 1: scanf("%d",&x); LCT::access(x); break;
                case 2:
                    scanf("%d%d",&x,&y);
                    printf("%d
    ",SegTree::querymx(1,1,n,Tree::in[x],Tree::in[x])+SegTree::querymx(1,1,n,Tree::in[y],Tree::in[y])+1-2*SegTree::querymx(1,1,n,Tree::in[Tree::LCA(x,y)],Tree::in[Tree::LCA(x,y)])); break;
                case 3: scanf("%d",&x); printf("%d
    ",SegTree::querymx(1,1,n,Tree::in[x],Tree::out[x]));break;
            }
        }
    }
    

      

  • 相关阅读:
    CQUOJ 10819 MUH and House of Cards
    CQUOJ 9920 Ladder
    CQUOJ 9906 Little Girl and Maximum XOR
    CQUOJ 10672 Kolya and Tandem Repeat
    CQUOJ 9711 Primes on Interval
    指针试水
    Another test
    Test
    二分图匹配的重要概念以及匈牙利算法
    二分图最大匹配
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6737564.html
Copyright © 2011-2022 走看看