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;
}
//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;
}
相关文章推荐
- poj&nbsp;3321&nbsp;Apple&nbsp;Tree(树状数组)
- poj&nbsp;1308&nbsp;Is&nbsp;It&nbsp;A&nbsp;Tree?(并查集)
- poj&nbsp;3013&nbsp;Big&nbsp;Christmas&nbsp;Tree&nbsp;(spf…
- poj&nbsp;3013&nbsp;Big&nbsp;Christmas&nbsp;Tree&nbsp;(解…
- poj&nbsp;2486&nbsp;Apple&nbsp;Tree&nbsp;tree&nbsp;dp
- poj 1741 Tree
- poj 1741 Tree
- poj&nbsp;3321&nbsp;Apple&nbsp;Tree&nbsp;线段树
- poj 1848 Tree
- poj 1848 Tree
- poj&nbsp;2255&nbsp;Tree&nbsp;Recovery
- poj&nbsp;Allantis&nbsp;(面积计算)1155线段…
- ext4 treePanel 设计节点级联选中
- poj 3128 Leonardo's Notebook
- poj 2253 Frogger
- poj 2635 The Embarrassed Crypto…
- POJ&nbsp;2262
- POJ&nbsp;1674
- 【RMQ&LCA】Cartesian Tree(笛卡…
- POJ&nbsp;2116