【POJ3321】Apple Tree(DFS序,树状数组)

题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作

1.将某个结点的苹果数异或 1
2.查询一棵子树内的苹果数
n,m<=100000
 
思路:最近一段时间在思考树上统计问题的算法
发现询问一棵子树中信息的问题一般都是DFS序+线段树或BIT维护
树上两点之间的查询一般都是树剖维护
比如说这题,单点修改+区间查询子树信息,转化为DFS序用BIT维护即可
注意有一个性质:U在DFS序中第一次出现的时刻是b[u],则它的子树就是区间(b[u],b[u]+size[u]-1)
 1 var t:array[0..1000000]of longint;
 2     head,vet,next,a,b,c,size,flag:array[1..500000]of longint;
 3     n,m,x,y,i,j,tot,time,p:longint;
 4     ch:string;
 5 
 6 procedure add(a,b:longint);
 7 begin
 8  inc(tot);
 9  next[tot]:=head[a];
10  vet[tot]:=b;
11  head[a]:=tot;
12 end;
13 
14 procedure dfs(u:longint);
15 var e,v:longint;
16 begin
17  flag[u]:=1;
18  inc(time); a[time]:=u; b[u]:=time; size[u]:=1;
19  e:=head[u];
20  while e<>0 do
21  begin
22   v:=vet[e];
23   if flag[v]=0 then
24   begin
25    dfs(v);
26    size[u]:=size[u]+size[v];
27   end;
28   e:=next[e];
29  end;
30 end;
31 
32 function lowbit(x:longint):longint;
33 begin
34  exit(x and (-x));
35 end;
36 
37 procedure update(x,p:longint);
38 begin
39  while x<=n do
40  begin
41   t[x]:=t[x]+p;
42   x:=x+lowbit(x);
43  end;
44 end;
45 
46 function sum(x:longint):longint;
47 begin
48  sum:=0;
49  while x>0 do
50  begin
51   sum:=sum+t[x];
52   x:=x-lowbit(x);
53  end;
54 end;
55 
56 begin
57  assign(input,'poj3321.in'); reset(input);
58  assign(output,'poj3321.out'); rewrite(output);
59  readln(n);
60  for i:=1 to n-1 do
61  begin
62   readln(x,y);
63   add(x,y);
64   add(y,x);
65  end;
66  dfs(1);
67  for i:=1 to n do
68  begin
69   c[i]:=1;
70   update(b[i],1);
71  end;
72  readln(m);
73  for i:=1 to m do
74  begin
75   readln(ch);
76   x:=0;
77   for j:=3 to length(ch) do x:=x*10+ord(ch[j])-ord('0');
78   if ch[1]='C' then
79   begin
80    if c[x]=1 then p:=-1
81     else p:=1;
82    update(b[x],p);
83    c[x]:=c[x] xor 1;
84   end;
85   if ch[1]='Q' then writeln(sum(b[x]+size[x]-1)-sum(b[x]-1));
86  end;
87  close(input);
88  close(output);
89 end.

 

 

posted on 2016-12-05 19:35  myx12345  阅读(810)  评论(0编辑  收藏  举报

导航