题目链接
大意:给你一棵树,问你树上距离等于x的无序点对个数
点分治模板题,直接做

#include<bits/stdc++.h>
 
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define LL long long
#define SZ(X) X.size()
#define pii pair<int,int>
#define ALL(X) X.begin(),X.end()
 
using namespace std;
 
LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL powmod(LL a, LL b, LL MOD) {LL ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
const int N = 5e4 + 11;
int n, X, vis[N];
vector<int>v[N];
LL ans;
int x;
int rt, siz[N], son[N];
void root(int o, int p) {
	siz[o] = 1;
	int M = 0;
	for (auto k : v[o]) {
		if (vis[k] || k == p)continue;
		root(k, o);
		siz[o] += siz[k];
		M = max(M, siz[k]);
	}
	M = max(M, n - siz[o]);
	if (!rt || M < X) {
		X = M;
		rt = o;
	}
}
int num[N];
int res[N];
void get(int o, int pa, int dis) {
	if (dis <= x)ans += num[x - dis], res[dis]++;
	if (dis >= x)return;
	for (auto k : v[o]) {
		if (k == pa || vis[k])continue;
		get(k, o, dis + 1);
	}
}
void dfs(int now) {
	vis[now] = 1;
	for (int i = 1; i <= x; i++)num[i] = 0; num[0] = 1;
	for (auto k : v[now]) {
		if (vis[k])continue;
		for (int i = 0; i <= x; i++)res[i] = 0;
		get(k, now, 1);
		for (int i = 0; i <= x; i++)num[i] += res[i];
	}
	for (auto k : v[now]) {
		rt = 0;
		if (vis[k])continue;
		n = siz[k];
		root(k, now);
		dfs(rt);
	}
	return ;
}
int main() {
	ios::sync_with_stdio(false);
	cin >> n >> x;
	for (int i = 1; i < n; i++) {
		int s, t;
		cin >> s >> t;
		v[s].pb(t);
		v[t].pb(s);
	}
	root(1, 0);
	root(rt, 0);
	dfs(rt);
	cout << ans  << endl;
	return 0;
}