1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
   | #include<cstdio> #include<cstring> #include<algorithm> #define RG register
  inline int read() { 	int data = 0, w = 1; 	char ch = getchar(); 	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); 	if(ch == '-') w = -1, ch = getchar(); 	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar(); 	return data * w; }
  const int maxn(100010); struct edge { int next, to; } e[maxn << 1]; int head[maxn], e_num, n; inline void add_edge(int from, int to) { 	e[++e_num] = (edge) {head[from], to}; 	head[from] = e_num; }
  int dep[maxn], heavy[maxn], maxdep[maxn]; void dfs(int x, int fa) { 	 	for(RG int i = head[x]; i; i = e[i].next) 	{ 		int to = e[i].to; if(to == fa) continue; 		dfs(to, x); maxdep[x] = std::max(maxdep[x], maxdep[to]); 		if(maxdep[to] > maxdep[heavy[x]]) heavy[x] = to; 	} 	maxdep[x] = maxdep[heavy[x]] + 1; 	 }
  long long *f[maxn], *g[maxn], pool[maxn << 2], *id = pool, ans; void calc(int x, int fa) { 	if(heavy[x]) f[heavy[x]] = f[x] + 1, 		g[heavy[x]] = g[x] - 1, calc(heavy[x], x); 	f[x][0] = 1, ans += g[x][0]; 	for(RG int i = head[x]; i; i = e[i].next) 	{ 		int to = e[i].to; if(to == fa || to == heavy[x]) continue; 		f[to] = id; id += maxdep[to] << 1; g[to] = id; id += maxdep[to] << 1; 		calc(to, x); 		for(RG int j = 0; j < maxdep[to]; j++) 		{ 			if(j) ans += f[x][j - 1] * g[to][j]; 			ans += g[x][j + 1] * f[to][j]; 		} 		for(RG int j = 0; j < maxdep[to]; j++) 		{ 			g[x][j + 1] += f[x][j + 1] * f[to][j]; 			if(j) g[x][j - 1] += g[to][j]; 			f[x][j + 1] += f[to][j]; 		} 	} }
  int main() { 	n = read(); 	for(RG int i = 1, a, b; i < n; i++) 		a = read(), b = read(), add_edge(a, b), add_edge(b, a); 	dfs(1, 0); f[1] = id; id += maxdep[1] << 1; g[1] = id; id += maxdep[1] << 1; 	calc(1, 0); printf("%lld\n", ans); 	return 0; }
   |