debug了一晚上bug,竟然是爆了int 。再次感叹自己的码力
点分治模板,求距离在 n-L-1,n-R-2 区间内的点对数,
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+50;
#define ll long long
struct Node{int to,nex;}e[M<<1];
int n,L,R,mx,sum,rt,cnt,siz[M],head[M<<1],v[M],p[M];
ll res;
void add(int x,int y){
e[cnt].to=y;e[cnt].nex=head[x];head[x]=cnt++;
e[cnt].to=x;e[cnt].nex=head[y];head[y]=cnt++;
}
void getrt(int x,int f){
siz[x]=1;int mm=0;
for(int to,i=head[x];~i;i=e[i].nex){
to=e[i].to;
if(to==f||v[to])continue;
getrt(to,x);
siz[x]+=siz[to];
if(mm<siz[to])mm=siz[to];
}
if(mm<sum-siz[x])mm=sum-siz[x];
if(mx>mm)mx=mm,rt=x;
}
void getdis(int x,int f,int dis,int k){
if(dis>k)return ;
p[++p[0]]=dis;
for(int to,i=head[x];~i;i=e[i].nex){
to=e[i].to;
if(to==f||v[to])continue;
getdis(to,x,dis+1,k);
}
}
ll cal(int x,int dis,int k){
ll ans=0;p[0]=0;
getdis(x,-1,dis,k);
sort(p+1,p+p[0]+1);
for(int i=1,j=p[0];i<j;i++){
while(p[i]+p[j]>k&&i<j)j--;
ans+=j-i;
}
return ans;
}
void work(int x,int k){
res+=cal(x,0,k);
v[x]=1;
for(int to,i=head[x];~i;i=e[i].nex){
to=e[i].to;
if(v[to])continue;
res-=cal(to,1,k);
mx=0x3f3f3f3f;
sum=siz[to];//t点
getrt(to,-1);
work(rt,k);
}
}
ll slove(int k){
if(k<=0)return 0;
res=0;
memset(v,0,sizeof(v));
mx=0x3f3f3f3f;sum=n;
getrt(1,-1);work(rt,k);
return res;
}
int main(){
// freopen("awesome.in","r",stdin);
int T;cin>>T;
while(T--){
memset(head,-1,sizeof(head));cnt=1;
cin>>n>>L>>R;
for(int x,y,i=1;i<n;i++)cin>>x>>y,add(x,y);
cout<<slove(n-L-1)-slove(n-R-2)<<endl;
}
return 0;
}