• 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;
            }
        }
    }
    

      

  • 相关阅读:
    jQuery Easing 动画效果扩展--使用Easing插件,让你的动画更具美感。
    JavaScript表达式--掌握最全的表达式,一切尽在掌握中,让表达不再是难事
    JavaScript的格式--从格式做起,做最严谨的工程师
    JavaScript 简介--对javascript的初识,最基础的了解
    手机web页面制作时的注意事项
    实现像淘宝一样牛的语音搜索框
    Cufon在渲染网页字体你不知道的事
    .net中单选按钮RadioButton,RadioButtonList 以及纯Html中radio的用法实例?
    使用C#把发表的时间改为几个月,几天前,几小时前,几分钟前,或几秒前
    eval解析JSON中的注意点
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6737564.html
Copyright © 2020-2023  润新知