• [NOI2015]软件包管理器


    四年前的noi我现在还切不掉我觉得我可以退役了


    题目链接:https://www.luogu.org/problem/P2146

    题目大意:不想写了

    树剖,记下重儿子,然后用线段树维护一下就AC了

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=400010;
    priority_queue<int> Q;
    char c[20];
    int T,kk,n,m,head[MAXN],ver[MAXN],nxt[MAXN],tot,fa[MAXN],dep[MAXN],son[MAXN],top[MAXN],pps[MAXN],sz[MAXN],tot2,sum[MAXN],lz[MAXN],x,bf;
    void add(int x,int y){
        ver[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }void dfs1(int x){
        dep[x]=dep[fa[x]]+1,sz[x]=1;
        for (int i=head[x];i;i=nxt[i]){
            if (ver[i]==fa[x]) continue;
            fa[ver[i]]=x;dfs1(ver[i]);sz[x]+=sz[ver[i]];
            if (sz[ver[i]]>sz[son[x]]) son[x]=ver[i];
        }
    }void dfs2(int x,int fa){
        pps[x]=++tot2,top[x]=fa;
        if (!son[x]) return;
        dfs2(son[x],fa);
        for (int i=head[x];i;i=nxt[i])
            if(!pps[ver[i]]) dfs2(ver[i],ver[i]);
    }void upp(int x){sum[x]=sum[x<<1]+sum[x<<1|1];}
    void pushdown(int i,int l,int r){
        if (lz[i]==0) return;int mid=l+r>>1;
        if (lz[i]==-1) sum[i<<1]=sum[i<<1|1]=0,lz[i<<1]=lz[i<<1|1]=-1;
        else sum[i<<1]=mid-l+1,sum[i<<1|1]=r-mid,lz[i<<1]=lz[i<<1|1]=1;
        lz[i]=0;return;
    }void update(int i,int l,int r,int ql,int qr,int x){
        if (ql<=l&&r<=qr){
            if (!x)lz[i]=-1,sum[i]=0;
            else lz[i]=1,sum[i]=r-l+1;
            return;
        }int mid=l+r>>1;pushdown(i,l,r);
        if (mid>=ql) update(i<<1,l,mid,ql,qr,x);
        if (mid<qr) update(i<<1|1,mid+1,r,ql,qr,x);
        upp(i);
    }void change(int v,int x,int y){
        while (top[x]!=top[y]){
            if (dep[top[x]]<dep[top[y]]) swap(x,y);
            update(1,1,n,pps[top[x]],pps[x],v);
            x=fa[top[x]];
        }if (dep[x]>dep[y]) swap(x,y);
        update(1,1,n,pps[x],pps[y],v);
    }int main(){
        scanf("%d",&n);
        for (int i=2;i<=n;i++){
            scanf("%d",&kk);
            add(++kk,i);add(i,kk);
        }scanf("%d",&T);dfs1(1),dfs2(1,1);
        while (T--){
            cin>>c+1;scanf("%d",&kk);bf=sum[1];++kk;
            if (c[1]=='i'){
                change(1,kk,1);
                printf("%d
    ",abs(sum[1]-bf));
            }else{
                update(1,1,n,pps[kk],pps[kk]+sz[kk]-1,0);
                printf("%d
    ",abs(sum[1]-bf));
            }
        }return 0;
    }
  • 相关阅读:
    GoCN每日新闻(2019-11-03)
    GoCN每日新闻(2019-11-02)
    GoCN每日新闻(2019-11-01)
    GoCN每日新闻(2019-10-31)
    GoCN每日新闻(2019-10-30)
    GoCN每日新闻(2019-10-29)
    xms西软预定列表-房类市场
    GoCN每日新闻(2019-10-28)
    GoCN每日新闻(2019-10-27)
    GoCN每日新闻(2019-10-26)
  • 原文地址:https://www.cnblogs.com/XYH-xyh/p/11847328.html
Copyright © 2020-2023  润新知