【BZOJ】4196:【NOI2015】软件包管理器-树剖

传送门:bzoj4196


代码

树剖水题……

#include
using namespace std;

const int N=1e5+10;

int tot,n,Q,df[N],ot[N],cnt,son[N],tp[N],sz[N];
int f[N],head[N],to[N],nxt[N],d[N],rt;
int sum[N<<2],in,cgd[N<<2];
char s[20];

inline int rd()
{
   char ch=getchar();int x=0,f=1;
   while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
   while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
   return x*f;
}

inline void lk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
inline void pushup(int k){sum[k]=sum[k<<1]+sum[k<<1|1];}
inline void pushdown(int k,int l,int r)
{
   if(!cgd[k]) return;
   if(cgd[k]==-1) sum[k<<1]=sum[k<<1|1]=0,cgd[k<<1]=cgd[k<<1|1]=-1;
   else{
     int mid=(l+r)>>1;
     sum[k<<1]=(mid-l+1);sum[k<<1|1]=(r-mid);
     cgd[k<<1]=cgd[k<<1|1]=1;
   }
   cgd[k]=0;
}


inline void dfs(int x)
{
    sz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        d[to[i]]=d[x]+1;dfs(to[i]);
        sz[x]+=sz[to[i]];
        if(son[x]==0 || sz[son[x]]inline void dsf(int x,int top)
{
    df[x]=++cnt;tp[x]=top;
    if(!son[x]){ot[x]=cnt;return;}
    dsf(son[x],top);
    for(int i=head[x];i;i=nxt[i]){
        if(to[i]==son[x]) continue;
        dsf(to[i],to[i]);
    }
    ot[x]=cnt;
}

inline int get(int k,int l,int r,int L,int R)
{
    if(l>=L  && r<=R) return sum[k];
    pushdown(k,l,r);
    int mid=(l+r)>>1;int ret=0;
    if(L<=mid) ret+=get(k<<1,l,mid,L,R);
    if(R>mid) ret+=get(k<<1|1,mid+1,r,L,R);
    return ret;
}

inline void sett(int k,int l,int r,int L,int R,int val)
{
    if(l>=L && r<=R){
       if(val==1) sum[k]=r-l+1;
       else sum[k]=0;
       cgd[k]=val;return;
    }
    int mid=(l+r)>>1;
    if(L<=mid) sett(k<<1,l,mid,L,R,val);
    if(R>mid) sett(k<<1|1,mid+1,r,L,R,val);
    pushup(k);
}

inline void instal(int x)
{
    int as=d[x]+1;
    while(x!=-1){
        as-=get(1,1,n,df[tp[x]],df[x]);
        sett(1,1,n,df[tp[x]],df[x],1);
        x=f[tp[x]];
    }
    printf("%d\n",as);
}

inline void uinstal(int x)
{
    printf("%d\n",get(1,1,n,df[x],ot[x]));
    sett(1,1,n,df[x],ot[x],-1);
}

int main(){
   n=rd();f[0]=-1;
   for(int i=1;i0);dsf(0,0);
   Q=rd();
   while(Q--){
     scanf("%s",s);
     if(s[0]=='i'){instal(rd());}
     else uinstal(rd());
   }
   return 0;
}

你可能感兴趣的:(树链剖分)