题意:给一棵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.