luogu2146 [NOI2015]软件包管理器

Posted poorpool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu2146 [NOI2015]软件包管理器相关的知识,希望对你有一定的参考价值。

安装就把根节点到它全设为 1
删除就把以它为根的子树全设为 0
记得标记初始化为-1,因为标记是 0 的情况也是要处理的。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, m, uu, hea[100005], cnt, dep[100005], fa[100005], son[100005], siz[100005];
int top[100005], idx[100005], qwq;
char ss[15];
struct Edge{
    int too, nxt;
}edge[200005];
struct SGT{
    int sum[400005], tag[400005];
    void build(int o, int l, int r){
        tag[o] = -1;
        if(l==r)    sum[o] = 0;
        else{
            int mid=(l+r)>>1;
            int lson=o<<1;
            int rson=lson|1;
            if(l<=mid)  build(lson, l, mid);
            if(mid<r)   build(rson, mid+1, r);
            sum[o] = sum[lson] + sum[rson];
        }
    }
    void pushDown(int o, int l, int r, int lson, int rson, int mid){
        tag[lson] = tag[o];
        tag[rson] = tag[o];
        sum[lson] = (mid-l+1) * tag[o];
        sum[rson] = (r-mid) * tag[o];
        tag[o] = -1;
    }
    void update(int o, int l, int r, int x, int y, int k){
        if(l>=x && r<=y){
            sum[o] = (r-l+1) * k;
            tag[o] = k;
        }
        else{
            int mid=(l+r)>>1;
            int lson=o<<1;
            int rson=lson|1;
            if(tag[o]!=-1)  pushDown(o, l, r, lson, rson, mid);
            if(x<=mid)  update(lson, l, mid, x, y, k);
            if(mid<y)   update(rson, mid+1, r, x, y, k);
            sum[o] = sum[lson] + sum[rson];
        }
    }
}sgt;
void add_edge(int fro, int too){
    edge[++cnt].nxt = hea[fro];
    edge[cnt].too = too;
    hea[fro] = cnt;
}
void dfs1(int x, int f){
    dep[x] = dep[f] + 1;
    fa[x] = f;
    siz[x] = 1;
    int maxSon=-1;
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t!=f){
            dfs1(t, x);
            siz[x] += siz[t];
            if(siz[t]>maxSon)   maxSon = siz[t], son[x] = t;
        }
    }
}
void dfs2(int x, int topf){
    top[x] = topf;
    idx[x] = ++qwq;
    if(!son[x]) return ;
    dfs2(son[x], topf);
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t!=fa[x] && t!=son[x])
            dfs2(t, t);
    }
}
void upd(int xx, int yy){
    while(top[xx]!=top[yy]){
        if(dep[top[xx]]<dep[top[yy]])   swap(xx, yy);
        sgt.update(1, 1, n, idx[top[xx]], idx[xx], 1);
        xx = fa[top[xx]];
    }
    if(dep[xx]>dep[yy]) swap(xx, yy);
    sgt.update(1, 1, n, idx[xx], idx[yy], 1);
}
int main(){
    cin>>n;
    for(int i=2; i<=n; i++){
        scanf("%d", &uu);
        add_edge(i, uu+1);
        add_edge(uu+1, i);
    }
    dfs1(1, 0);
    dfs2(1, 1);
    sgt.build(1, 1, n);
    cin>>m;
    while(m--){
        scanf("%s %d", ss, &uu);
        uu++;
        if(ss[0]==‘i‘){
            int tmp=sgt.sum[1];
            upd(1, uu);
            printf("%d\n", sgt.sum[1]-tmp);
        }
        else{
            int tmp=sgt.sum[1];
            sgt.update(1, 1, n, idx[uu], idx[uu]+siz[uu]-1, 0);
            printf("%d\n", tmp-sgt.sum[1]);
        }
    }
    return 0;
}

以上是关于luogu2146 [NOI2015]软件包管理器的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P2146 [NOI2015]软件包管理器树链剖分

洛谷 P2146 [NOI2015]软件包管理器 (树链剖分模板题)

BZOJ4196:[NOI2015]软件包管理器——题解

Luogu P2146软件包管理器

Luogu P2146 软件包管理器(树链剖分+线段树)

[树链剖分][线段树] Luogu P2146 软件包管理器