8481 Triples of Cows

描述

There are initially N−1 pairs of friends among FJ’s N cows labeled 1…N, forming a tree. The cows are
leaving the farm for vacation one by one. On day i, the i th cow leaves the
farm, and then all pairs of the i th cow’s friends still present on the farm
become friends.

For each i from 1 to N, just before the i th cow leaves, how many
ordered triples of distinct cows (a,b,c) are there such that none of a,b,c
are on vacation, a is friends with b, and b is friends with c?

农夫约翰有 N 头奶牛,编号 1∼N。

最初时,奶牛之间有 N−1 对两两朋友关系,这些关系可以构成一棵树。

假期来临,奶牛们一只接着一只的离开农场去度假。

在第 i 天,第 i 头奶牛会离开农场,并且在它离开后,所有仍在农场的第 i 头奶牛的朋友两两之间都会成为朋友。

对于从 1 到 N 的每个 i,请你计算,在第 i 头奶牛即将离开之时(轮到它离开了,但它还没离开),有多少个有序奶牛三元组 (a,b,c) 满足奶牛 a,b,c 仍在农场,且 a 和 b 是朋友,b 和 c 是朋友。

输入描述

The first line contains N.

The next N−1 lines contain two integers ui​ and vi​ denoting that cows
ui​ and vi​ are initially friends.

第一行包含整数 N。

接下来 N−1 行,每行包含两个整数 ui​,vi​,表示奶牛 ui​ 和 vi​ 最初是朋友。

输出描述

The answers for i from 1 to N on separate lines.

共 N 行,第 i 行输出在第 i 头奶牛即将离开之时,满足条件的有序奶牛三元组的数量。

样例输入 1 

3
1 2
2 3

样例输出 1 

2
0
0

样例输入 2 

4
1 2
1 3
1 4

样例输出 2 

6
6
0
0

样例输入 3 

5
3 5
5 1
1 4
1 2

样例输出 3 

8
10
2
0
0

提示

数据范围与提示

2≤N≤2×105,1≤ui​,vi​≤N

For the first sample:
(1,2,3) and (3,2,1) are the triples just before cow 1 leaves.
After cow
1 leaves, there are less than 3 cows left, so no triples are possible.

For the second sample:
At the beginning, cow 1 is friends with all other cows, and no other pairs of
cows are friends, so the triples are (a,1,c) where a,c are different cows
from {2,3,4}, which gives 3⋅2=6 triples.
After cow 1 leaves, the remaining three cows are all friends, so the triples
are just those three cows in any of the 3!=6 possible orders.
After cow 2 leaves, there are less than 3 cows left, so no triples are
possible.

2≤N≤2⋅105, 1≤ui​,vi​≤N.

  • Inputs 4-5: N≤500.
  • Inputs 6-10: N≤5000.
  • Inputs 11-20: No additional constraints.
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
int n,vis[200005],ffa[400005],fa[400005];
ll ans,f[400005],g[400005],h[400005];
vector<int>e[400005];
int root(int x){
	if(x==fa[x])return x;
	return fa[x]=root(fa[x]);
}
ll qur(int x){
	if(!x)return 0;
	return (f[x]+1)*f[x]*(f[x]-1)-f[x]*f[x]+2*f[x]*h[x];//统计一个点的答案
}
void dfs(int u,int ft){
	ffa[u]=ft;
	for(auto v:e[u]){
		if(v==ft)continue;
		dfs(v,u);
		if(u<=n)g[u]+=f[v];
		else{
			f[u]++;
			h[u]+=g[v];
		}
	}
}
void del(int u){
	int f1=root(ffa[u]),f2=ffa[f1],f3=root(ffa[f2]);
	ans-=g[u]*g[u];
	ans-=qur(f1)+g[f2]*g[f2]+qur(f3);
	f[f1]--;g[f2]--;h[f3]--;
	for(auto v:e[u]){
		if(v==ffa[u])continue;
		ans-=qur(v);
		fa[v]=f1;
		f[f1]+=f[v];
		
		g[f2]+=f[v];
		
		h[f1]-=f[v];h[f1]+=h[v];
		
		h[f3]+=f[v];
	}
	ans+=qur(f1)+g[f2]*g[f2]+qur(f3);
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<n;++i){
		int a,b;
		cin>>a>>b;
		e[a].pb(n+i);e[n+i].pb(a);
		e[b].pb(n+i);e[n+i].pb(b);
	}
	dfs(n,0);
	for(int i=1;i<=n;++i)ans+=g[i]*g[i];
	for(int i=n+1;i<=2*n-1;++i)ans+=qur(i);
	for(int i=n+1;i<=2*n-1;++i)fa[i]=i;
	cout<<ans<<endl;
	for(int i=1;i<n;++i){
		del(i);//每次先删点进行更新
		cout<<ans<<endl;
	}
	return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值