牛客挑战赛45 E 旁观者

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

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

(n,m,kle 10^9)


神仙题。

我的1h<dyp的3分钟

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

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

图造出来了。最终的问题是算最终留下的(n-k)个,钦定(2)(或(3))个点在里面的概率。概率为(frac{inom{n-2}{n-k-2}}{inom{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
",sum);
	return 0;
}
原文地址:https://www.cnblogs.com/jz-597/p/13972201.html