poj 3321Apple Tree (解法2:线段…

来源:互联网 发布:java使用qq邮箱发邮件 编辑:程序博客网 时间:2024/04/29 15:24
题意思路见上一篇 主要难在建树上,有人说这不一定是根二叉树 但我却用二叉树 做对了,可能是他代码写得不对吧

//8184K   563MS

#include <stdio.h>
#include <string.h>
#define L(x) (x<<1)
#define R(x) ((x<<1)+1)
#define M 100010

int head[M],vis[M],low[M],high[M];
int p,dep,n;

struct data
{
    intto,next;
}edge[M];
struct tree
{
    intl,r,pick;          //pick 为1 表示该点有苹果
    intsum;
}node[3*M];

void addedge(int cu ,int cv)
{
    edge[p].to =cv;
    edge[p].next= head[cu];
    head[cu] =p++;
}

void dfs (int u)
{
    low[u] =++dep;
    vis[u] =1;
    for (int i =head[u];i != -1;i  = edge[i].next)
       while (!vis[edge[i].to])
           dfs (edge[i].to);
    high[u] =dep;
}

void BuildTree(int left,int right,int u)
{
    node[u].l =left;
    node[u].r =right;
    node[u].pick=1;     //建树的时候就得把树的值全部初始化 因为它可能一开始就查询
    if (left ==right)
    {
       node[u].sum = 1;
       return ;
    }
    int mid =(left + right)>>1;
   BuildTree(left,mid,L(u));
   BuildTree(mid+1,right,R(u));
    node[u].sum= node[L(u)].sum + node[R(u)].sum;
}
void getdown (int u)
{
    node[u].pick= 0;
   node[L(u)].pick = 1;
   node[L(u)].sum = node[L(u)].r - node[L(u)].l + 1;
   node[R(u)].pick = 1;
   node[R(u)].sum = node[R(u)].r - node[R(u)].l + 1;
}
void updata (int num ,int u)
{
    if(node[u].l == num&&node[u].r ==num)
    {
       if (node[u].pick == 1)
       {
           node[u].pick = 0;
           node[u].sum = 0;
       }
       else
       {
           node[u].pick = 1;
           node[u].sum = 1;
       }
       return ;
    }
    if(node[u].pick)
       getdown (u);
    if (num<= node[L(u)].r)
       updata (num,L(u));
    else
       updata (num,R(u));
    node[u].sum= node[L(u)].sum + node[R(u)].sum;
    if(node[L(u)].pick&&node[R(u)].pick)
       node[u].pick = 1;
}
int query (int left,int right,int u)
{
    if(node[u].l == left&&node[u].r ==right)
       return node[u].sum;
    int mid =(node[u].l + node[u].r)>>1;
    if (right<= mid)
       return query (left,right,L(u));
    if (left>= mid+1)
       return query (left,right,R(u));

    int a =query (left,mid,L(u));
    int b =query (mid+1,right,R(u));
    return a +b;
}
int main ()
{
    intm,u,v,i;
    charop;
    while(~scanf ("%d",&n))
    {
       memset (head,-1,sizeof(head));
       memset (vis,0,sizeof (vis));
       p = dep = 0;
       for (i = 1;i < n;i ++)
       {
           scanf ("%d%d",&u,&v);
           addedge(u,v);
       }
       dfs (1);
       BuildTree(1,high[1],1);
       scanf ("%d",&m);
       while (m --)
       {
           getchar ();
           scanf ("%c %d",&op,&u);
           if (op == 'Q')
           {
               int ans = query (low[u],high[u],1);
               printf ("%d\n",ans);
           }
           else
               updata (low[u],1);
       }
    }
    return0;
}

原创粉丝点击