51NOD - 1677treecnt

題目鏈接:51NOD - 1677treecnt


顯然可以考慮每條邊的貢獻。

假設這條邊左邊s個點,右邊n-s個點。只有左右都有點,那麼這條邊就會貢獻答案。然後容斥計算就是總方案減去全在左邊或者全在右邊。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+7;
int n,k,sz[N],fac[N]={1},res;
vector<int> g[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
inline int qmi(int a,int b=mod-2){
	int res=1;
	while(b){if(b&1LL) res=res*a%mod; a=a*a%mod; b>>=1LL;}
	return res;
}
inline int C(int n,int m){
	if(m>n)	return 0;
	return fac[n]*qmi(fac[m])%mod*qmi(fac[n-m])%mod;
}
void dfs(int x,int fa){
	sz[x]=1;
	for(auto to:g[x])	if(to!=fa){
		dfs(to,x);	int s=sz[to];
		res=(res+(C(n,k)-C(n-s,k)-C(s,k))%mod+mod)%mod;
		sz[x]+=sz[to];
	}
}
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)	fac[i]=fac[i-1]*i%mod;
	for(int i=1,a,b;i<n;i++)	scanf("%lld %lld",&a,&b),add(a,b);
	dfs(1,1);	cout<<res;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章