ここら辺はまだ簡単。
https://yukicoder.me/problems/no/1098
問題
根付き木が与えられる。
f(k)を、頂点対(u,v)のうちLCAが頂点kになるものの数とする。
各kに対しf(k)を求めよ。
解法
頂点kの各子頂点のSubtreeの頂点数からなる配列をCとする。
2つの異なる子頂点のSubTreeから2点選ぶ、もしくは1個以上の頂点をkとすると、LCAがkになる。
よって
となる。
int N; vector<int> E[202020]; int C[202020]; ll ret[202020]; int dfs(int cur,int pre) { C[cur]=1; ret[cur]=1; FORR(e,E[cur]) if(e!=pre) { int add=dfs(e,cur); ret[cur]+=2LL*C[cur]*add; C[cur]+=add; } return C[cur]; } void solve() { int i,j,k,l,r,x,y; string s; cin>>N; FOR(i,N-1) { cin>>x>>y; E[x].push_back(y); E[y].push_back(x); } dfs(1,1); FOR(i,N) cout<<ret[i+1]<<endl; }
まとめ
これは★2.5でもいいかもね。