[NOIP2016-day1-T2]天天愛跑步running_題解


題目來源:http://www.lydsy.com/JudgeOnline/problem.php?id=4719

鎮樓圖:

     noip滾粗后、、訂正的第一題。

題目大意:

      有若干條路徑在一棵樹上,問每個點恰為多少條路徑起點出發Ti長度處。

解題方略:

      這題可以O(n)。。結果shy非常有趣地在考場上碼80分暴力、結果還爆QAQ(這題,80分做法,比100分做法難吧。。)

      考慮把詢問分成不同的兩個鏈。但是,如果有鏈的話,就不可避免要樹剖。然而其實不必。利用DFS的性質,可以知道,在一個點打標記,可以影響到它的子樹(相對地,也可以是所有父親)。那么,我們考慮暴力,就是詢問每個點x,子樹里有多少個d[u]=d[x]+t[x]或d[v]-len[u,v]=d[x]-t[x],復雜度O(n*子樹大小)。那么,這個只要一個桶就可以記錄。求LCA只要tarjan離線就可以O(n+m),這里暫時把並查集的復雜度也看成常數倍。那么,有些人就會卡在子樹的合並上。其實並不用合並。因為,一個點退出時,我們即知,其子樹的操作都已經實施過(添加/刪除),那么,我們只需在進入時算一遍Ans、退出時算一遍Ans,兩者的差就是子樹的貢獻。

AC代碼:

       這里bzoj之前數據有漏導致WA了,事情咋那么多呢TAT。

 1 {$M 100000000,0,100000000}
 2 type
 3  Chitose=record
 4   e:longint;
 5   head     :array[0..300005]of longint;
 6   next,node:array[0..600005]of longint
 7  end;
 8  Chitoge=array[-600005..600005]of longint;
 9 var
10  n,m,i,u,v:longint;
11  t,d,z,s,Ans:array[0..300005]of longint;
12  p,q:Chitoge;
13  o,a:Chitose;
14  f,g:array[0..1]of Chitose;
15  
16 procedure ad(var x:Chitose;u,v:longint);
17 begin
18  with x do
19  begin
20   inc(e);
21   next[e]:=head[u];
22   head[u]:=e;
23   node[e]:=v
24  end
25 end;
26  
27 function fd(x:longint):longint;
28 begin if x<>z[x] then z[x]:=fd(z[x]); exit(z[x]) end;
29  
30 procedure sk(u:longint);
31 var i,v,w,x,y,c:longint;
32 begin
33  z[u]:=u;
34  i:=o.head[u];
35  while i<>0 do
36  begin
37   v:=o.node[i];
38   if d[v]=0 then begin d[v]:=d[u]+1; sk(v); z[v]:=u end;
39   i:=o.next[i]
40  end;
41  i:=a.head[u];
42  while i<>0 do
43  begin
44   w:=a.node[i]>>1;
45   if s[w]=0 then s[w]:=u
46       else begin v:=s[w];
47                  c:=fd(v);
48                  s[w]:=d[v]+d[u]-2*d[c];
49                  if odd(a.node[i]) then begin x:=v; y:=u end
50                                    else begin x:=u; y:=v end;
51                  ad(f[0],x,d[x]);
52                  ad(f[1],c,d[x]);
53                  ad(g[0],y,d[y]-s[w]);
54                  ad(g[1],c,d[y]-s[w]) end;
55   i:=a.next[i]
56  end
57 end;
58  
59 procedure __Claris(u:longint);
60 var i,v:longint;
61 begin
62  z[u]:=0;
63  Ans[u]:=p[d[u]+t[u]]+q[d[u]-t[u]];
64  i:=f[0].head[u]; while i<>0 do begin inc(p[f[0].node[i]]); i:=f[0].next[i] end;
65  i:=g[0].head[u]; while i<>0 do begin inc(q[g[0].node[i]]); i:=g[0].next[i] end;
66  i:=o.head[u];
67  while i<>0 do
68  begin
69   v:=o.node[i];
70   if z[v]<>0 then __Claris(v);
71   i:=o.next[i]
72  end;
73  i:=f[1].head[u]; while i<>0 do begin dec(p[f[1].node[i]]); i:=f[1].next[i] end; Ans[u]:=p[d[u]+t[u]]+q[d[u]-t[u]]-Ans[u];
74  i:=g[1].head[u]; while i<>0 do begin dec(q[g[1].node[i]]); i:=g[1].next[i] end;
75 end;
76  
77 begin
78  read(n,m);
79  for i:=2 to n do
80  begin
81   read(u,v);
82   ad(o,u,v);
83   ad(o,v,u)
84  end;
85  for i:=1 to n do read(t[i]);
86  for i:=1 to m do
87  begin
88   read(u,v);
89   ad(a,u,i<<1);
90   ad(a,v,i<<1+1)
91  end;
92  d[1]:=1;
93  sk(1);
94  __Claris(1);
95  write(Ans[1]); for i:=2 to n do write(' ',Ans[i])
96 end.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM