题意:有一颗苹果树,树上有n个节点,每个节点最多有一个苹果。一开始,每个节点上有一个苹果。定义操作Q i为询问以节点i为根节点的子树上有多少个苹果,C i为改变节点i的苹果数(原来为1,则变为0,反之相反)最多有100000个节点。
分析:先进行一次dfs,把每个节点的dfs序记录下来,那么就把树转换成了一个序列。很容易得知一个节点的子树一定是该序列的一个子序列,那么剩下的就是裸的树状数组了。
代码:
const maxn=100000; var e,n,dep,root:longint; num,l,r,last,v,a:array[1..maxn] of longint; side:array[1..maxn] of record x,y,next:longint; end; procedure add(x,y:longint); begin inc(e); side[e].x:=x; side[e].y:=y; side[e].next:=last[x]; last[x]:=e; end; procedure init; var i,x,y:longint; begin readln(n); fillchar(v,sizeof(v),0); for i:=1 to n-1 do begin readln(x,y); add(x,y); v[y]:=1; end; for i:=1 to n do if v[i]=0 then begin root:=i; break; end; end; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; function lowbit(x:longint):longint; begin lowbit:=x and -x; end; procedure dfs(x:longint); var i:longint; begin inc(dep); num[x]:=dep; l[x]:=dep; r[x]:=dep; i:=last[x]; while i>0 do with side[i] do begin dfs(y); l[x]:=min(l[x],l[y]); r[x]:=max(r[x],r[y]); i:=next; end; end; procedure updata(x,delta:longint); var i:longint; begin i:=x; while i<=n do begin a[i]:=a[i]+delta; i:=i+lowbit(i); end; end; function sum(x:longint):longint; var i:longint; begin sum:=0; i:=x; while i>0 do begin sum:=sum+a[i]; i:=i-lowbit(i); end; end; procedure main; var m,i,x,delta:longint; c:char; begin dfs(root); for i:=1 to n do begin a[i]:=lowbit(i); v[i]:=1; end; readln(m); for i:=1 to m do begin read(c); if c='C' then begin readln(x); if v[x]=1 then delta:=-1 else delta:=1; v[x]:=1-v[x]; updata(num[x],delta); end else begin readln(x); writeln(sum(r[x])-sum(l[x]-1)); end; end; end; begin init; main; end.