开始zz写了一个主席树,后来发现写个树状数组就行~
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bits/stdc++.h>
#define N 100005
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int length,weight;
namespace BIT
{
int C[N];
int lowbit(int t)
{
return t&(-t);
}
void update(int x,int v)
{
for(;x<N;x+=lowbit(x)) C[x]+=v;
}
int query(int x)
{
int re=0;
for(;x>0;x-=lowbit(x)) re+=C[x];
return re;
}
};
ll answer;
struct Node
{
int u,d1,d2;
Node(int u=0,int d1=0,int d2=0):u(u),d1(d1),d2(d2){}
};
vector<Node>v;
bool cmp(Node a,Node b)
{
return a.d2<b.d2;
}
int n,edges,root,sn;
int hd[N],to[N<<1],nex[N<<1],val[N<<1];
int size[N],mx[N],vis[N],rt[N];
void add(int u,int v,int c)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
}
void getroot(int u,int ff)
{
size[u]=1,mx[u]=0;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]);
mx[u]=max(mx[u],sn-size[u]);
if(mx[u]<mx[root]) root=u;
}
// d1<=l d2<=w
void getdis(int u,int ff,int d1,int d2)
{
v.push_back(Node(u,d1,d2));
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
getdis(to[i],u,d1+1,d2+val[i]);
}
ll calc(int u,int D1,int D2)
{
getdis(u,0,D1,D2);
sort(v.begin(),v.end(),cmp);
ll re=0;
int i,j,l=0,r=(int)v.size()-1;
for(i=1;i<(int)v.size();++i) BIT::update(v[i].d1+1,1);
while(l<r)
{
if(v[l].d2+v[r].d2<=weight)
{
re+=(ll)BIT::query(length-v[l].d1+1);
++l,BIT::update(v[l].d1+1,-1);
}
else
{
BIT::update(v[r].d1+1,-1);
--r;
}
}
v.clear();
return re;
}
void solve(int u)
{
vis[u]=1;
answer+=calc(u,0,0);
for(int i=hd[u];i;i=nex[i]) if(!vis[to[i]]) answer-=calc(to[i],1,val[i]);
for(int i=hd[u];i;i=nex[i])
if(!vis[to[i]])
sn=size[to[i]],root=0,getroot(to[i],u),solve(root);
}
int main()
{
int i,j;
// setIO("input");
scanf("%d%d%d",&n,&length,&weight);
for(i=1;i<n;++i)
{
int a=i+1,b,c;
scanf("%d%d",&b,&c),add(a,b,c),add(b,a,c);
}
mx[root=0]=sn=n,getroot(1,0),solve(root);
printf("%lld\n",answer);
return 0;
}