#树链剖分,线段树#洛谷 2146 [NOI2015]软件包管理器

题目传送门


分析

安装时1到\(x\)路径上都变为1,删除时\(x\)的子树都变为0,
显然可以用树链剖分+线段树实现


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011; struct node{int y,next;}e[N<<1];
int dep[N],ls[N],fat[N],top[N],dfn[N],tot,son[N],big[N],w[N<<2],lazy[N<<2],k=1,n;
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
inline void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
inline void add(int x,int y){
    e[++k]=(node){y,ls[x]},ls[x]=k,
    e[++k]=(node){x,ls[y]},ls[y]=k;
}
inline void dfs1(int x,int fa){
    dep[x]=dep[fa]+1,fat[x]=fa,son[x]=1;
    for (rr int i=ls[x],mson=-1;i;i=e[i].next)
    if (e[i].y!=fa){
        dfs1(e[i].y,x);
        son[x]+=son[e[i].y];
        if (son[e[i].y]>mson) big[x]=e[i].y,mson=son[e[i].y];
    }
}
inline void dfs2(int x,int linp){
    dfn[x]=++tot,top[x]=linp;
    if (!big[x]) return; dfs2(big[x],linp);
    for (rr int i=ls[x];i;i=e[i].next)
    if (e[i].y!=fat[x]&&e[i].y!=big[x]) dfs2(e[i].y,e[i].y);
}
inline void update(int k,int l,int r,int x,int y,int z){
    if (l==x&&r==y) {w[k]=~z?r-l+1:0,lazy[k]=z; return;}
    rr int mid=(l+r)>>1;
    if (lazy[k]){
        rr int t=lazy[k]; lazy[k]=0;
        w[k<<1]=~t?mid-l+1:0,lazy[k<<1]=t,
        w[k<<1|1]=~t?r-mid:0,lazy[k<<1|1]=t;
    }
    if (y<=mid) update(k<<1,l,mid,x,y,z);
    else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
    else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
    w[k]=w[k<<1]+w[k<<1|1];
}
inline void Update(int x,int y){
    while (top[x]!=top[y]){
        if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
        update(1,1,n,dfn[top[x]],dfn[x],1),x=fat[top[x]];
    }
    if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
    update(1,1,n,dfn[x],dfn[y],1);
}
signed main(){
    n=iut();
    for (rr int i=2;i<=n;++i) add(i,iut()+1);
    dfs1(1,0),dfs2(1,1);
    for (rr int Q=iut();Q;--Q,putchar(10)){
        rr char c=getchar();
        while (!isalpha(c)) c=getchar();
        rr int t=w[1],x=iut()+1;
        if (c=='i') Update(1,x),print(w[1]-t);
        else update(1,1,n,dfn[x],dfn[x]+son[x]-1,-1),print(t-w[1]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Spare-No-Effort/p/12355110.html