Hungry3

梦想到达塔顶的蜗牛

zoj 3686 线段树 先topo一次给所以结点编号就行了

#include<cstdio>
#include<vector>
using namespace std;
#define pb push_back
#define maxn 100000+100
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ls rt<<1
#define rs ls|1
int sum[maxn<<2],col[maxn<<2];
int L[maxn],R[maxn];
vector<int> G[maxn];
int id;
void dfs(int u)
{
    int i,j,v;
    L[u]=++id;
    for(i=0;i<G[u].size();i++)
    {
        v=G[u][i];
        dfs(v);
    }
    R[u]=id;
}
void build(int l,int r,int rt)
{
    sum[rt]=0;
    col[rt]=0;
    if(l==r)return;
    int m=(l+r)/2;
    build(lson),build(rson);
}
void Up(int rt)
{
    sum[rt]=sum[ls]+sum[rs];
}
void Down(int l,int r,int rt)
{
    int m=(l+r)/2;
    if(col[rt])
    {
        col[ls]^=1;
        col[rs]^=1;
        col[rt]=0;
        sum[ls]=(m-l+1)-sum[ls];
        sum[rs]=(r-m)-sum[rs];
    }
}
void update(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        col[rt]^=1;
        sum[rt]=(r-l+1)-sum[rt];
        return;
    }
    int m=(l+r)/2;
    Down(l,r,rt);
    if(L<=m)update(L,R,lson);
    if(m<R)update(L,R,rson);
    Up(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        return sum[rt];
    }
    Down(l,r,rt);
    int res=0;
    int m=(l+r)/2;
    if(L<=m)res+=query(L,R,lson);
    if(m<R)res+=query(L,R,rson);
    return res;
}
int main()
{
    int n,m;
    int i,j,x;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++)
        G[i].clear();
        for(i=2;i<=n;i++)
        {
            scanf("%d",&x);
            G[x].pb(i);
        }
        id=0;
        dfs(1);
        build(1,n,1);
        while(m--)
        {
            int nod;
            char op[2];
            scanf("%s%d",op,&nod);
            if(op[0]=='o')
            update(L[nod],R[nod],1,n,1);
            else printf("%d\n",query(L[nod],R[nod],1,n,1));
        }
        printf("\n");
    }
}
View Code

 

posted on 2013-11-10 14:43  Hungry3  阅读(168)  评论(0)    收藏  举报

导航