正解:点分治+树状数组。
点分治板子题,直接点分以后按照$w$排序,扫指针的时候把$w$合法的路径以$l$为下标加入树状数组统计就行了。
写这道题只是想看看我要写多久。。事实证明我确实是老年选手了,这种傻逼题写+调竟然用了$40min$。。
1 #include <bits/stdc++.h>
2 #define il inline
3 #define RG register
4 #define ll long long
5 #define lb(x) (x & -x)
6 #define N (300005)
7
8 using namespace std;
9
10 struct edge{ int nt,to,dis; }g[N];
11 struct data{ int l,w; }st[N];
12
13 int head[N],vis[N],dis[N],len[N],son[N],sz[N],c[N],l,w,n,num,top;
14 ll ans;
15
16 il int gi(){
17 RG int x=0,q=1; RG char ch=getchar();
18 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
19 if (ch=='-') q=-1,ch=getchar();
20 while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
21 return q*x;
22 }
23
24 il void insert(RG int from,RG int to,RG int dis){
25 g[++num]=(edge){head[from],to,dis},head[from]=num; return;
26 }
27
28 il int cmp(const data &a,const data &b){ return a.w<b.w; }
29
30 il void add(RG int x,RG int v){
31 if (!x) c[0]+=v; else for (;x<=n;x+=lb(x)) c[x]+=v; return;
32 }
33
34 il int query(RG int x){
35 RG int res=c[0]; for (;x;x^=lb(x)) res+=c[x]; return res;
36 }
37
38 il void getrt(RG int x,RG int p,RG int &rt){
39 son[x]=0,sz[x]=1;
40 for (RG int i=head[x],v;i;i=g[i].nt){
41 v=g[i].to; if (v==p || vis[v]) continue;
42 getrt(v,x,rt),sz[x]+=sz[v],son[x]=max(son[x],sz[v]);
43 }
44 son[x]=max(son[x],son[0]-sz[x]);
45 if (son[rt]>=son[x]) rt=x; return;
46 }
47
48 il void getdis(RG int x,RG int p){
49 st[++top]=(data){len[x],dis[x]},sz[x]=1;
50 for (RG int i=head[x],v;i;i=g[i].nt){
51 v=g[i].to; if (v==p || vis[v]) continue;
52 len[v]=len[x]+1,dis[v]=dis[x]+g[i].dis;
53 getdis(v,x),sz[x]+=sz[v];
54 }
55 return;
56 }
57
58 il void calc(RG int rt,RG int llim,RG int wlim,RG int fg){
59 len[rt]=llim,dis[rt]=wlim,getdis(rt,top=0);
60 sort(st+1,st+top+1,cmp); RG int p=1;
61 for (RG int i=top;i;--i){
62 while (p<=top && st[p].w+st[i].w<=w) add(st[p++].l,1);
63 if (l>=st[i].l) ans+=fg*query(l-st[i].l);
64 }
65 for (RG int i=1;i<p;++i) add(st[i].l,-1); return;
66 }
67
68 il void solve(RG int x,RG int S){
69 RG int rt=0; son[0]=S,getrt(x,0,rt),vis[rt]=1,calc(rt,0,0,1);
70 for (RG int i=head[rt];i;i=g[i].nt)
71 if (!vis[g[i].to]) calc(g[i].to,1,g[i].dis,-1);
72 for (RG int i=head[rt];i;i=g[i].nt)
73 if (!vis[g[i].to]) solve(g[i].to,sz[g[i].to]);
74 return;
75 }
76
77 int main(){
78 #ifndef ONLINE_JUDGE
79 freopen("vertices.in","r",stdin);
80 freopen("vertices.out","w",stdout);
81 #endif
82 n=gi(),l=gi(),w=gi();
83 for (RG int i=2,p,d;i<=n;++i)
84 p=gi(),d=gi(),insert(p,i,d),insert(i,p,d);
85 solve(1,n),cout<<(ans-n)/2; return 0;
86 }
来源:oschina
链接:https://my.oschina.net/u/4356045/blog/4057697