其实这道题和以前在poj上做过的将树映射到树状数组的题目很像
首先不难想到,将一条边从土路修成公路,只对以这条边连接的孩子结点为根的子树有影响;
于是和之前那道poj的题目很像,后序遍历树,对每个节点重标号,每个点初始值就是深度
下面的问题就变成了:
土路修成公路---->区间修改
查询从点1到某个点所经过的土路数----->单点求值;
这种问题我们其实可以用树状数组来做;
a[i]表示原数组的值;
令c[i]=a[i]-a[i-1],特殊的c[1]=a[1];
然后我们对c数组做树状数组
区间修改(假设是[l,r]都+1)就是c[l]+1,c[r+1]-1;
单点求值就是求signma(c[1~i])
当然后来知道其实用dfs序更简单
1 type node=record 2 point,next:longint; 3 end; 4 5 var fa,a,c,p,r,h,d:array[0..260000] of longint; 6 edge:array[0..510000] of node; 7 len,n,m,x,y,t,i:longint; 8 ch:char; 9 10 procedure add(x,y:longint); 11 begin 12 inc(len); 13 edge[len].point:=y; 14 edge[len].next:=p[x]; 15 p[x]:=len; 16 end; 17 18 function lowbit(x:longint):longint; 19 begin 20 exit(x and (-x)); 21 end; 22 23 procedure work(x,f:longint); 24 begin 25 while x<=n do 26 begin 27 inc(a[x],f); 28 x:=x+lowbit(x); 29 end; 30 end; 31 32 function ask(x:longint):longint; 33 begin 34 ask:=0; 35 while x>0 do 36 begin 37 ask:=ask+a[x]; 38 x:=x-lowbit(x); 39 end; 40 end; 41 42 procedure dfs(x,d:longint); 43 var i,y,tmp:longint; 44 begin 45 i:=p[x]; 46 c[x]:=d; 47 tmp:=n+1; 48 while i<>-1 do 49 begin 50 y:=edge[i].point; 51 if (c[y]=0) and (y<>1) then 52 begin 53 fa[y]:=x; 54 dfs(y,d+1); 55 if tmp>h[y] then tmp:=h[y]; 56 end; 57 i:=edge[i].next; 58 end; 59 inc(t); 60 r[x]:=t; 61 if tmp=n+1 then h[x]:=r[x] 62 else h[x]:=tmp; 63 end; 64 65 begin 66 len:=-1; 67 fillchar(p,sizeof(p),255); 68 readln(n); 69 for i:=1 to n-1 do 70 begin 71 readln(x,y); 72 add(x,y); 73 add(y,x); 74 end; 75 t:=0; 76 dfs(1,0); 77 for i:=1 to n do 78 d[r[i]]:=c[i]; 79 for i:=2 to n do 80 work(i,d[i]-d[i-1]); 81 work(1,d[1]); 82 readln(m); 83 for i:=1 to n+m-1 do 84 begin 85 read(ch); 86 if ch='W' then 87 begin 88 readln(x); 89 writeln(ask(r[x])); 90 end 91 else begin 92 readln(x,y); 93 if fa[x]=y then t:=x else t:=y; 94 work(h[t],-1); 95 work(r[t]+1,1); 96 end; 97 end; 98 end.