题解 luogu P7474 「C.E.L.U-02」学术精神

第一问

\qquad 对于第一问,我们只要思考一个点要向外连出一条边的期望次数最后将其乘以 n n n 即可. 有两种思路:
\qquad 1.对于期望次数,在第 i i i次连到不是自己的概率为 n − 1 n i \frac{n-1}{n^i} nin1.那么最后我们所求的就是 a n s ( s i n g l e ) = ∑ i = 1 + ∞ n − 1 n i ∗ i ans(single)=\sum_{i=1}^{+\infty}\frac{n-1}{n^i}*i ans(single)=i=1+nin1i,通过差比数列求和之后可以得出 a n s ( s i n g l e ) → n n − 1 ans(single)\to\frac{n}{n-1} ans(single)n1n,则 a n s = n 2 n − 1 ans=\frac{n^2}{n-1} ans=n1n2.
\qquad 2.每次选到别的边的概率为 n − 1 n \frac{n-1}{n} nn1,又因为这是一个几何分布,所以期望就是概率的倒数,也就是 a n s ( s i n g l e ) = n n − 1 ans(single)=\frac{n}{n-1} ans(single)=n1n,感性的理解的话就是对于这个模型而言, n n n次里面会有 n − 1 n-1 n1次符合要求,那么我们平均只需要抽 n n − 1 \frac{n}{n-1} n1n次,就会有一次符合要求。即 a n s ( s i n g l e ) = n n − 1 ans(single)=\frac{n}{n-1} ans(single)=n1n。那么最后的答案就是 a n s = n 2 n − 1 ans=\frac{n^2}{n-1} ans=n1n2.

第二问

\qquad 对于第二问,由于它是考虑连通块的个数,所以向自己连边的统统不用考虑,简而言之,第二问与第一问无关。
\qquad 这里有一个结论就是在本题条件下,对于每一个确定的图,图的联通块数与其所含环的数量相等。那么我们只需要计算出在所有的图中总共有多少环,再除以图的数量,那么就是最后的答案了。
\qquad 令环的总数为 S u m Sum Sum,图的总数为 N u m Num Num.
\qquad N u m = ( n − 1 ) n S u m = ∑ i = 2 n ∗ C n i ∗ ( i − 1 ) ! ∗ ( n − 1 ) n − i Num=(n-1)^n\\ \qquad\quad Sum=\sum_{i=2}^{n}*C_{n}^{i}*(i-1)!*(n-1)^{n-i} Num=(n1)nSum=i=2nCni(i1)!(n1)ni
\qquad 解释一下 S u m Sum Sum的含义,首先我们先确定环的大小 i i i,然后从 n n n个点中选择 i i i个成环,可以形成环的种类是 ( i − 1 ) ! (i-1)! (i1)!(圆排列),其余点随便连边,最后对其求和(每个确定的环在多少图中出现过)。因为 Σ \Sigma Σ所有的图中有多少环是与 Σ \Sigma Σ每个确定的环在多少图中出现过的数值是等价的,所以可以进行如上计算。

最后附上AC代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e2+5,p=1e9+7;
inline ll read() {
	register ll x=0,f=1;
	register char ch=getchar();
	while(ch<'0'||ch>'9') {
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
ll n,inv[N],fac[N],ct[N];
ll po(ll x, int y) {
	register int ans=1;
	while(y>0) {
		if(y&1)ans=(ans*x)%p;
		y>>=1;
		x=(x*x)%p;
	}
	return ans;
}
ll C(int x,int y){
	return fac[x]*inv[y]%p*inv[x-y]%p;
}
int main() {
	register ll ans=0;
	n=read(),ct[0]=inv[1]=inv[0]=fac[0]=fac[1]=1;
	ct[1]=n-1;
	for(register int i=2;i<=n;i++){
		ct[i]=ct[i-1]*(n-1)%p;
		fac[i]=fac[i-1]*i%p;
		inv[i]=(p-p/i)*inv[p%i];
	}
	for(register int i=2;i<=n;i++)inv[i]=inv[i-1]*inv[i]%p;
	for(register int i=2;i<=n;i++){
		ans+=(C(n,i)*fac[i-1]%p*ct[n-i]%p);
		ans%=p;
	}
	ans=(ans*po(ct[n],p-2)%p+p)%p;
	printf("%lld\n%lld",n*n%p*po(n-1,p-2)%p,ans);
	return 0;
}
//有防作弊操作,请不要复制。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值