codeforces 293E Close Vertices
正解:点分治+树状数组。
点分治板子题,直接点分以后按照$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 }