牛客挑战赛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;
}