题目:
题意:
给定一颗边权全为 1 的树,求两两点之间距离的平方的和
分析:
如果是求两两之间距离的和,直接树形dp算每条边的贡献即可;现在题目要求距离平方的和,还是考虑树形dp枚举每条边计算每条边的贡献,套路地将平方展开看一下,比如算: (a+b+c)*(a+b+c) = a^2 + a*(b+c) + b^2 + b*(a+c) + c^2 + c*(a+b),发现对于每一条边它的贡献都是一样的计算方式,边权又为 1,那么每条边的贡献就是经过这条边的所有路径的长度和,这个只需要维护子树节点的个数和子树节点到根的距离和就能 O(1) 快速计算,树形dp枚举每条边就做完了
代码:
#include <bits/stdc++.h>
#define x first
#define y second
#define pii pair<int,int>
#define sz(x) (int)(x).size()
#define Max(x,y) (x)>(y)?(x):(y)
#define Min(x,y) (x)<(y)?(x):(y)
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef long long LL;
const int maxn = 1e6+16;
const int mod = 998244353;
inline int read(){
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){if(c == '-')f=-1; c=getchar();}
while(