• 【BZOJ3153】—Sone1(Top-Tree)


    传送门

    AC这道超级工业题留念

    由于LctLct并不能支持子树操作,所以有了这种神奇的数据结构

    好像实际上是叫AAAAAA
    我也不清楚实际上和TopTreeTop-Tree有啥区别…

    大致思想就是在LctLct上每个节点22个儿子变成四个儿子
    多的2个作为另外一颗splaysplay的根的左右儿子
    这个splaysplay用来维护所有虚儿子

    于是子树操作就可以在这个splaysplay上打标记啦
    由于各个儿子之间没有大小关系,所以必须全部设在叶子节点,其他点相当于是虚点

    据说有9696的常数QwQQwQ

    而且不知道为什么
    肯定是太naiive而且没有丰富的人生经验
    导致LCTLCT里信息维护错了之类的奇怪的问题
    要在不必要(雾)的地方加一些东西才能过
    比如splaysplay最后得pushuppushup
    linklink之后要accessaccess之类的
    已经放弃治疗了

    具体实现可以看ClarisClaris的博客

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>  
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int inf=1<<30;
    struct tag{
        int mul,add;
        tag(){mul=1,add=0;}
        tag(int _m,int _a){mul=_m,add=_a;}
        inline bool empty(){return mul==1&&!add;}
        friend inline tag operator +(cs tag &a,cs tag &b){
            return tag(a.mul*b.mul,b.mul*a.add+b.add);
        }
        void operator +=(cs tag &a){*this=*this+a;}
        inline int calc(int x){return x*mul+add;}
    };
    struct node{
        int s,mn,mx,siz;
        node(){s=siz=0,mn=inf,mx=-inf;}
        node(int x){s=mn=mx=x,siz=1;}
        node(int _s,int _mn,int _mx,int _siz){s=_s,mn=_mn,mx=_mx,siz=_siz;}
        friend inline node operator +(cs node &a,cs node &b){
            return node(a.s+b.s,min(a.mn,b.mn),max(a.mx,b.mx),a.siz+b.siz);
        }
        void operator +=(cs node &a){*this=*this+a;}
        friend inline node operator +(cs node &a,tag b){
            return a.siz?node(a.s*b.mul+a.siz*b.add,b.calc(a.mn),b.calc(a.mx),a.siz):a;
        }
        void operator +=(tag a){*this=*this+a;}
    };
    int rt;
    cs int N=200005;
    namespace AT{
        int fa[N],son[N][4],stk[N],top,rev[N],in[N],val[N],tot;
        node sc[N],st[N],sa[N];
        tag ct[N],tt[N];
        #define lc(u) son[u][0]
        #define rc(u) son[u][1]
        #define pc(u) son[u][2]
        #define qc(u) son[u][3]
        inline void delet(int u){
            stk[++top]=u;
            lc(u)=rc(u)=pc(u)=qc(u)=rev[u]=in[u]=val[u]=fa[u]=0;
        }
        inline int newnode(){
            int u=top?stk[top--]:++tot;
            in[u]=1;return u;
        }
        inline void initnode(int u,int k){
            st[u]=node(),sa[u]=sc[u]=node(k),val[u]=k;
        }
        inline bool isrt(int u,int t){
            if(!fa[u])return 1;
            if(t)return !in[u]||!in[fa[u]];
            return (lc(fa[u])!=u&&rc(fa[u])!=u)||in[fa[u]]||in[u];
        }
        inline void pushrev(int u){
            swap(lc(u),rc(u)),rev[u]^=1;
        }
        inline void pushnowc(int u,tag k){
            sc[u]+=k,sa[u]=sc[u]+st[u];
            val[u]=k.calc(val[u]),ct[u]+=k;
        }
        inline void pushnowt(int u,tag k,int t){
            st[u]+=k,tt[u]+=k;
            if(!in[u]&&t)pushnowc(u,k);
            else sa[u]=sc[u]+st[u];
        }
        inline void pushdown(int u){
            if(rev[u]){
                if(lc(u))pushrev(lc(u));
                if(rc(u))pushrev(rc(u));
                rev[u]=0;
            }
            if(!in[u]&&!ct[u].empty()){
                if(lc(u))pushnowc(lc(u),ct[u]);
                if(rc(u))pushnowc(rc(u),ct[u]);
                ct[u]=tag();
            }
            if(!tt[u].empty()){
                if(lc(u))pushnowt(lc(u),tt[u],0);
                if(rc(u))pushnowt(rc(u),tt[u],0);
                if(pc(u))pushnowt(pc(u),tt[u],1);
                if(qc(u))pushnowt(qc(u),tt[u],1);
                tt[u]=tag();
            }
        }
        inline void pushup(int u){
            st[u]=node();
            if(lc(u))st[u]+=st[lc(u)];
            if(rc(u))st[u]+=st[rc(u)];
            if(pc(u))st[u]+=sa[pc(u)];
            if(qc(u))st[u]+=sa[qc(u)];
            if(in[u])
                sc[u]=node(),sa[u]=st[u];
            else{
                sc[u]=node(val[u]);
                if(lc(u))sc[u]+=sc[lc(u)];
                if(rc(u))sc[u]+=sc[rc(u)];
                sa[u]=sc[u]+st[u];
            }
        }
        inline int posit(int u){
            if(lc(fa[u])==u)return 0;
            if(rc(fa[u])==u)return 1;
            if(pc(fa[u])==u)return 2;
            if(qc(fa[u])==u)return 3;
            return 4;
        }
        inline void rotate(int v,int t){
            int u=fa[v],pp=(son[u][t+1]==v)+t,z=fa[u],kk;
            fa[v]=z;
            if(z&&(kk=posit(u))!=4)son[z][kk]=v;
            son[u][pp]=son[v][pp^1];
            if(son[v][pp^1])fa[son[v][pp^1]]=u;
            fa[u]=v,son[v][pp^1]=u;
            pushup(u),pushup(v);
        }
        int q[N];
        inline void pushall(int u,int t){
            q[q[0]=1]=u;
            for(int v=u;!isrt(v,t);v=fa[v])q[++q[0]]=fa[v];
            for(int i=q[0];i;i--)pushdown(q[i]);
        }
        inline void splay(int u,int t=0){
            pushall(u,t);
            while(!isrt(u,t)){
                if(!isrt(fa[u],t))
                ((son[fa[fa[u]]][t]==fa[u])^(son[fa[u]][t]==u))?rotate(u,t):rotate(fa[u],t);//????
                rotate(u,t);
            }pushup(u);
        }
        inline int getson(int u,int t){
            pushdown(son[u][t]);return son[u][t];
        }
        inline void setson(int u,int t,int v){
            son[u][t]=v,fa[v]=u;
        }
        inline void add(int u,int v){
            if(!v)return;
            pushdown(u);
            if(!pc(u))return setson(u,2,v);
            if(!qc(u))return setson(u,3,v);
            while(pc(u)&&in[pc(u)])u=getson(u,2);
            int z=newnode();
            setson(z,2,pc(u));
            setson(z,3,v);
            setson(u,2,z);
            splay(z,2);
        }
        inline void del(int u){
            if(!u)return;
            splay(u);
            if(!fa[u])return;
            int v=fa[u];
            if(in[v]){
                pushall(v,2);
                int z=fa[v];
                if(z)setson(z,posit(v),getson(v,posit(u)^1)),splay(z,2);
                delet(v);
            }
            else son[v][posit(u)]=0,splay(v);
            fa[u]=0;
        }
        inline int Fa(int u){
            splay(u);
            if(!fa[u])return 0;
            if(!in[fa[u]])return fa[u];
            int t=fa[u];
            splay(fa[u],2);
            return fa[t];
        }
        inline int access(int u){
            int v=0;
            for(;u;v=u,u=Fa(u)){
                splay(u),del(v);
                add(u,rc(u)),setson(u,1,v);
                pushup(u);
            }
            return v;
        }
        inline void makert(int u){
            access(u),splay(u),pushrev(u);
        }
        inline void link(int u,int v){
            makert(u),access(v),add(v,u),access(u);
        }
        inline void cut(int u){
            access(u),splay(u);
            fa[lc(u)]=0,lc(u)=0;
            pushup(u);
        }
        inline int Lca(int u,int v){
            access(u);return access(v);
        }
        inline void updatec(int u,int v,tag k){
            makert(u),access(v),splay(v);
            pushnowc(v,k),makert(rt);
        }
        inline void updatet(int u,tag k){
            access(u),splay(u);
            val[u]=k.calc(val[u]);
            if(pc(u))pushnowt(pc(u),k,1);
            if(qc(u))pushnowt(qc(u),k,1);
            pushup(u),splay(u);
        }
        inline node queryc(int u,int v){
            makert(u),access(v),splay(v);
            node res=sc[v];makert(rt);return res;
        }
        inline node queryt(int u){
            access(u),splay(u);
            node res=node(val[u]);
            if(pc(u))res+=sa[pc(u)];
            if(qc(u))res+=sa[qc(u)];
            return res;
        }
    }
    int n,m;
    pii e[N];
    int main(){
        n=read(),m=read();
        AT::tot=n;
        for(int i=2;i<=n;i++)e[i].fi=read(),e[i].se=read();
        for(int i=1;i<=n;i++)AT::initnode(i,read());
        for(int i=2;i<=n;i++)AT::link(e[i].fi,e[i].se);
        rt=read();
        AT::makert(rt);
        while(m--){
            int op=read();
            int u=read();
            if(op==0){
                int k=read();
                AT::updatet(u,tag(0,k));
            }
            else if(op==1)
                AT::makert(u);
            else if(op==2){
                int v=read(),k=read();
                AT::updatec(u,v,tag(0,k));
            }
            else if(op==3)
                cout<<AT::queryt(u).mn<<'
    ';
            else if(op==4)
    			cout<<AT::queryt(u).mx<<'
    ';
            else if(op==5){
                int k=read();
                AT::updatet(u,tag(1,k));
            }
            else if(op==6){
                int v=read(),k=read();
                AT::updatec(u,v,tag(1,k));
            }
            else if(op==7){
                int v=read();
                cout<<AT::queryc(u,v).mn<<'
    ';
            }
            else if(op==8){
                int v=read();
                cout<<AT::queryc(u,v).mx<<'
    ';
            }
            else if(op==9){
                int v=read();
                if(AT::Lca(u,v)==u)continue;
                AT::cut(u),AT::link(v,u);
                AT::makert(rt);
            }
            else if(op==10){
                int v=read();
                cout<<AT::queryc(u,v).s<<'
    ';
            }
            else cout<<AT::queryt(u).s<<'
    ';
        }
    }
    
  • 相关阅读:
    C51学习 之 中断
    C51学习 之 动态数码管
    C51学习 之 LED流水灯
    锁存器 工作功能
    keil 5下载地址
    成本与利润最大化问题
    记一次VS下LINK1169的错误
    合并链表
    设计推特
    线段求交点
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328507.html
Copyright © 2020-2023  润新知