牛客挑战赛45 E 旁观者

构造一个\(n\)个点,\(m\)条边的仙人掌,使得随机删\(k\)个点之后期望的连通块个数尽量大。

输出这个最大的期望的连通块数。

\(n,m,k\le 10^9\)


神仙题。

我的1h<dyp的3分钟

考虑正难则反,最终\(连通块数=点数-边数+环数\)

点数和边数可以算,于是我们希望最大化最终剩下的期望环数。这时候可以感觉到钦定每个环长度为\(3\)是最好选择,并且这样的情况也是可以构造的,比如先构造个菊花图,然后给一些叶子节点之间连边。

图造出来了。最终的问题是算最终留下的\(n-k\)个,钦定\(2\)(或\(3\))个点在里面的概率。概率为\(\frac{\binom{n-2}{n-k-2}}{\binom{n}{n-k}}\),化简之后可以快速算。


using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mo 1000000007
#define ll long long
ll n,m,k;
ll qpow(ll x,ll y=mo-2){
	ll r=1;
	for (;y;y>>=1,x=x*x%mo)
		if (y&1)
			r=r*x%mo;
	return r;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%lld%lld%lld",&n,&m,&k);
	k=n-k;
	ll c=m-n+1;
	ll sum=k-(k*(k-1)%mo)*qpow(n*(n-1)%mo)%mo*m%mo+(k*(k-1)%mo*(k-2)%mo)*qpow(n*(n-1)%mo*(n-2)%mo)%mo*c%mo;
	sum=(sum%mo+mo)%mo;
//	ll sum=2*(n-1)*qpow(n)%mo*k%mo+C2(k)*qpow(C2(n))%mo*m%mo;
	printf("%lld\n",sum);
	return 0;
}
posted @ 2020-11-14 07:50  jz_597  阅读(111)  评论(0编辑  收藏  举报