您的位置:首页 > 移动开发

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

2013-04-23 09:25 447 查看
题意思路见上一篇 主要难在建树上,有人说这不一定是根二叉树 但我却用二叉树 做对了,可能是他代码写得不对吧

//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

{

int
to,next;

}edge[M];

struct tree

{

int
l,r,pick;
//pick 为1 表示该点有苹果

int
sum;

}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 ()

{

int
m,u,v,i;

char
op;

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);

}

}

return
0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: