其实这道题和以前在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.
View Code

 

posted on 2014-07-06 17:34  acphile  阅读(140)  评论(0编辑  收藏  举报