由于路径的深度是升序的
所以我们可以考虑用前缀和的思想,用sum维护点到根路径上节点和
对于每个点x存在路径和为s即这个点到根的路径上存在y,使sum[x]-sum[y]=s
这显然是可以二分的

 1 type node=record
 2        po,next:longint;
 3      end;
 4 
 5 var w:array[0..100010] of node;
 6     q,s,a,p:array[0..100010] of longint;
 7     len,t,n,m,x,y,ans,i:longint;
 8 
 9 procedure add(x,y:longint);
10   begin
11     inc(len);
12     w[len].po:=y;
13     w[len].next:=p[x];
14     p[x]:=len;
15   end;
16 
17 function find(l,r,x:longint):boolean;
18   var m:longint;
19   begin
20     while l<=r do
21     begin
22       m:=(l+r) shr 1;
23       if s[q[m]]=x then exit(true);
24       if s[q[m]]>x then r:=m-1 else l:=m+1;
25     end;
26     exit(false);
27   end;
28 
29 procedure dfs(x:longint);
30   var i,y:longint;
31   begin
32     inc(t);
33     q[t]:=x;
34     i:=p[x];
35     while i<>0 do
36     begin
37       y:=w[i].po;
38       s[y]:=s[x]+a[y];
39       if find(0,t,s[y]-m) then inc(ans);
40       dfs(y);
41       i:=w[i].next;
42     end;
43     dec(t);
44   end;
45 
46 begin
47   readln(n,m);
48   for i:=1 to n do
49     read(a[i]);
50   for i:=1 to n-1 do
51   begin
52     readln(x,y);
53     add(x,y);
54   end;
55   s[1]:=a[1];
56   q[0]:=0;
57   s[0]:=0;
58   dfs(1);
59   writeln(ans);
60 end.
View Code

 

posted on 2014-10-26 20:02  acphile  阅读(115)  评论(0编辑  收藏  举报