BZOJ 4196 软件包管理器

Posted on 2016-05-20 15:13  ziliuziliu  阅读(162)  评论(0编辑  收藏  举报

傻逼链剖。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 200500
#define maxe 200500
using namespace std;
int n,x,q,ls[maxv<<2],rs[maxv<<2],sum[maxv<<2],lazy[maxv<<2];
int cnt=0,tot=0,nume=0,g[maxv],root;
int top[maxv],fath[maxv],w[maxv],mx[maxv],size[maxv],son[maxv],dis[maxv];
char type[15];
struct edge
{
    int v,nxt;
}e[maxe];
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void dfs1(int x)
{
    size[x]=1;son[x]=0;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        fath[v]=x;dis[v]=dis[x]+1;
        dfs1(v);
        size[x]+=size[v];
        if (size[v]>size[son[x]])
            son[x]=v;
    }
}
void dfs2(int x,int father)
{
    top[x]=father;w[x]=++cnt;mx[x]=w[x];
    if (son[x]) dfs2(son[x],father);
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if ((v!=fath[x]) && (v!=son[x]))
            dfs2(v,v);
        mx[x]=max(mx[x],mx[v]);
    }
}
void build(int &now,int left,int right)
{
    now=++tot;lazy[now]=-1;sum[now]=right-left+1;
    if (left==right) return;
    int mid=(left+right)>>1;
    build(ls[now],left,mid);
    build(rs[now],mid+1,right);
}
void pushdown(int now,int left,int right)
{
    if (lazy[now]==-1) return;
    int mid=(left+right)>>1;
    if (lazy[now]==0)
    {
        lazy[ls[now]]=0;lazy[rs[now]]=0;
        sum[ls[now]]=mid-left+1;sum[rs[now]]=right-mid;
        lazy[now]=-1;
    }
    else
    {
        lazy[ls[now]]=1;lazy[rs[now]]=1;
        sum[ls[now]]=0;sum[rs[now]]=0;
        lazy[now]=-1;
    }
}
void pushup(int now)
{
    sum[now]=sum[ls[now]]+sum[rs[now]];
}
int modify(int now,int left,int right,int l,int r,int x)
{
    pushdown(now,left,right);
    if ((left==l) && (right==r))
    {
        if (x==0)
        {
            lazy[now]=0;int regis=sum[now];
            sum[now]=right-left+1;
            return sum[now]-regis;
        }
        else
        {
            lazy[now]=1;int regis=sum[now];
            sum[now]=0;
            return regis;
        }
    }
    int mid=(left+right)>>1,ans;
    if (r<=mid) ans=modify(ls[now],left,mid,l,r,x);
    else if (l>=mid+1) ans=modify(rs[now],mid+1,right,l,r,x);
    else ans=modify(ls[now],left,mid,l,mid,x)+modify(rs[now],mid+1,right,mid+1,r,x);
    pushup(now);
    return ans;    
}
void work1()
{
    scanf("%d",&x);x++;
    int regis=0,now=x;
    while (top[now]!=1)    
    {
        regis+=modify(root,1,cnt,w[top[now]],w[now],1);
        now=fath[top[now]];
    }
    regis+=modify(root,1,cnt,w[top[now]],w[now],1);
    printf("%d\n",regis);
}
void work2()
{
    scanf("%d",&x);x++;
    printf("%d\n",modify(root,1,cnt,w[x],mx[x],0));
}
int main()
{
    scanf("%d",&n);
    for (int i=2;i<=n;i++)
    {
        scanf("%d",&x);
        addedge(x+1,i);
    }
    dfs1(1);
    dfs2(1,1);
    build(root,1,cnt);
    scanf("%d",&q);
    for (int i=1;i<=q;i++)
    {
        scanf("%s",type);
        if (type[0]=='i') work1();
        else work2(); 
    }
    return 0;
}