• Luogu P2146 [NOI2015]软件包管理器 树剖


    卸载:把子树清空;

    安装:把自己到$1$的链改为$1$

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define R register int
    #define ls (tr<<1)
    #define rs (tr<<1|1)
    using namespace std;
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } const int N=100010;
    int n,m,cnt,num;
    int vr[N<<1],nxt[N<<1],fir[N],sz[N],top[N],dfn[N],pre[N],d[N],son[N],sum[N<<2],tg[N<<2];
    inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    inline void dfs1(int u) { sz[u]=1; R mx=0;
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(!d[v]) {
                d[v]=d[u]+1; dfs1(v); sz[u]+=sz[v];
                if(sz[v]>mx) son[u]=v,mx=sz[v];
            }
        }
    }
    inline void dfs2(int u,int tp) {
        top[u]=tp; dfn[u]=++num;
        if(son[u]) dfs2(son[u],tp);
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(v!=pre[u]&&v!=son[u]) dfs2(v,v);
        }
    }
    inline void spread(int tr,int l,int r) { if(~tg[tr]) {
            R md=l+r>>1;
            tg[ls]=tg[tr],sum[ls]=(md-l+1)*tg[tr];
            tg[rs]=tg[tr],sum[rs]=(r-md)*tg[tr]; tg[tr]=-1;
        }
    }
    inline void update(int tr,int l,int r,int LL,int RR,int d) {
        if(LL<=l&&r<=RR) {tg[tr]=d,sum[tr]=(r-l+1)*d; return ;} spread(tr,l,r); R md=l+r>>1;
        if(LL<=md) update(ls,l,md,LL,RR,d); if(RR>md) update(rs,md+1,r,LL,RR,d);
        sum[tr]=sum[ls]+sum[rs];
    }
    inline void change(int u,int inc) {
        while(top[u]!=1) {
            update(1,1,n,dfn[top[u]],dfn[u],inc);
            u=pre[top[u]];
        } update(1,1,n,1,dfn[u],inc);
    }
    signed main() { memset(tg,0xff,sizeof(tg));
        n=g(); for(R i=2,u;i<=n;++i) u=g()+1,add(u,i),add(i,u),pre[i]=u;
        d[1]=1,dfs1(1); dfs2(1,1); m=g(); 
        for(R i=1,x;i<=m;++i) { register char ch; while(!isalpha(ch=getchar()));
            R tmp=sum[1]; x=g()+1;
            if(ch=='i') change(x,1),printf("%d
    ",sum[1]-tmp);
            else if(ch=='u') {
                update(1,1,n,dfn[x],dfn[x]+sz[x]-1,0);
                printf("%d
    ",tmp-sum[1]);
            }
        }
    }

    2019.07.03

  • 相关阅读:
    NYOJ之Fibonacci数
    NYOJ之奇偶数分离
    NYOJ之喷水装置(一)
    借助LinkedHashMap实现基于LRU算法缓存
    素数距离问题
    NYOJ之ASCII码排序
    《Thinking in Java》十七章_容器深入研究_练习14(Page486)
    《Thinking in Java》十七章_容器深入研究_练习12(Page484)
    《Thinking in Java》十七章_容器深入研究_练习13(Page484)
    遍历目录
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11128461.html
Copyright © 2020-2023  润新知