zoukankan      html  css  js  c++  java
  • 【ZJOI2016】大森林

    这题理论上可以用ETT,但是用LCT建虚点可以解决这个问题。

    对于最晚的操作1建立一个虚点,然后把操作0挂上去。

    #include<bits/stdc++.h>
    const int N=4e5+5;
    using namespace std;
    struct Link_Cut_Tree{
        int size[N],w[N],c[N][2],fa[N],cnt,rev[N],q[N];
        inline void newnode(int x){++cnt;size[cnt]=w[cnt]=x;}
        inline bool isroot(int x){return (c[fa[x]][1]!=x&&c[fa[x]][0]!=x)||!x;}
        inline void pushup(int x){size[x]=size[c[x][0]]+size[c[x][1]]+w[x];}
        inline void pushdown(int x){
            int l=c[x][0],r=c[x][1];
            if(rev[x]){
                rev[l]^=1;rev[r]^=1;rev[x]^=1;
                swap(c[x][0],c[x][1]);
            }
        }
        inline void rotate(int x){
            int y=fa[x],z=fa[y],l,r;
            if(c[y][0]==x)l=0;else l=1;r=l^1;
            if(!isroot(y)){if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;}
            fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
            c[y][l]=c[x][r];c[x][r]=y;
            pushup(y);pushup(x);
        }
        inline void splay(int x){
            int top=1;q[top]=x;
            for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
            for(int i=top;i;i--)pushdown(q[i]);
            while(!isroot(x)){
                int y=fa[x],z=fa[y];
                if(!isroot(y)){
                    if((c[y][0]==x)^(c[z][0]==y))rotate(x);
                    else rotate(y);
                }rotate(x);
            }
            pushup(x);
        }
        inline int access(int x){int t=0;for(;x;t=x,x=fa[x])splay(x),c[x][1]=t,pushup(x);return t;}
        inline void cut(int x){access(x),splay(x),fa[c[x][0]]=0,c[x][0]=0;pushup(x);}
        inline void link(int x,int y){splay(x);fa[x]=y;}
    }T;
    struct Opt{
        int pos,opt,x,y;
        Opt(int pos=0,int opt=0,int x=0,int y=0):pos(pos),opt(opt),x(x),y(y){}
    }a[N];
    bool cmp(Opt a,Opt b){return a.pos==b.pos?a.opt<b.opt:a.pos<b.pos;}
    int n,m,op[N],ed[N],b[N],tot=1,ans[N],vis[N],top;
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int main(){
        n=read();m=read();int now=0;
        T.newnode(1);T.newnode(0);T.link(2,1);now=2;
        b[1]=1;op[1]=1;ed[1]=n;
        for(int i=1;i<=m;i++){
            int opt=read(),l=read(),r=read();
            if(opt==0){
                ++tot;T.newnode(1);
                b[tot]=T.cnt;op[tot]=l;ed[tot]=r;
                a[++top]=Opt(1,i-m,T.cnt,now);
            }
            else if(opt==1){
                int k=read();l=max(op[k],l);r=min(r,ed[k]);
                if(l<=r){
                    T.newnode(0);T.link(T.cnt,now);
                    a[++top]=Opt(l,i-m,T.cnt,b[k]);
                    a[++top]=Opt(r+1,i-m,T.cnt,now);
                    now=T.cnt;
                }
            }
            else{
                int k=read();vis[i]=1;
                a[++top]=Opt(l,i,b[r],b[k]);
            }
        }
        sort(a+1,a+top+1,cmp);int k=1,t=0;
        for(int i=1;i<=n;i++){
            for(;a[k].pos==i;k++){
                if((t=a[k].opt)>0){
                    int x=a[k].x,y=a[k].y;
                    T.access(x);T.splay(x);ans[t]+=T.size[x];
                    int lca=T.access(y);T.splay(y);ans[t]+=T.size[y];
                    T.access(lca);T.splay(lca);ans[t]-=T.size[lca]*2;
                }else{T.cut(a[k].x);T.link(a[k].x,a[k].y);}
            }
        }
        for(int i=1;i<=m;i++)if(vis[i])printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    hdu5834 Magic boy Bi Luo with his excited tree 【树形dp】
    POJ2152 Fire 【树形dp】
    POJ1848 Tree 【树形dp】
    hdu3586 Information Disturbing 【树形dp】
    BZOJ4557 [JLoi2016]侦察守卫 【树形dp】
    BZOJ4000 [TJOI2015]棋盘 【状压dp + 矩阵优化】
    BZOJ1487 [HNOI2009]无归岛 【仙人掌dp】
    BZOJ4002 [JLOI2015]有意义的字符串 【数学 + 矩乘】
    洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
    3-3 银行业务队列简单模拟
  • 原文地址:https://www.cnblogs.com/zcysky/p/7309447.html
Copyright © 2011-2022 走看看