NOIP模拟试题详讲2021/11/6

T1

题目大意:对于一个序列,将其随机排序,求使之单调不下降的期望。答案对1e9+7取模。

送分题,但本蒟蒻做不出来
首先我们来看看这个题:
求掷骰子掷到6的期望。

分析:
解法1:
对于掷了x次,就是掷到了概率为P,该次的期望次数就是1,没有掷到概率为 ( 1 − P ) (1-P) (1P),由于该次没有掷到,所以期望还是E(x)

E ( x ) = 1 + ( 1 − P ) E ( x ) E(x)=1+(1-P)E(x) E(x)=1+(1P)E(x)
E ( x ) = 1 P = 6 E(x)=\frac{1}{P}=6 E(x)=P1=6

解法2:
根据离散型随机变量期望公式为:
E = ∑ i = 1 ∞ X i P i E=\sum_{i=1}^{\infty}X_iP_i E=i=1XiPi
如果第一次掷到了6,期望为:
E = 1 × P E=1\times P E=1×P
如果第二次掷到了6,期望为:
E = 2 × ( 1 − P ) P E=2\times (1-P)P E=2×(1P)P
其中概率等于上一次没有掷到6概率,乘上这一次掷6的概率。
同理,第三次掷到了6,期望为:
E = 3 × ( 1 − P ) 2 P E=3\times(1-P)^2P E=3×(1P)2P
以此类推,我们得到总的期望为:
E = ∑ i = 0 ∞ ( i + 1 ) P ( P − 1 ) i E=\sum^{\infty}_{i=0}(i+1)P(P-1)^i E=i=0(i+1)P(P1)i
所以我们要求
E = lim ⁡ i → ∞ ∑ i = 0 ∞ ( i + 1 ) P ( P − 1 ) i E=\lim_{i\rightarrow\infty}\sum^{\infty}_{i=0}(i+1)P(P-1)^i E=ilimi=0(i+1)P(P1)i
最后 容易得到:
E = 1 P E=\frac{1}{P} E=P1

说了这么多,回到本题。
我们知道序列的全排列数为 n ! n! n!,那么将某一位放到正确的位置上的概率为:
P = 1 n ! P=\frac{1}{n!} P=n!1
但注意,序列中可能会有重复,所以去掉重复个数的全排列数,即:
P = ∑ x ! n ! P=\frac{\sum x!}{n!} P=n!x!
根据上面的,期望即为:
E = 1 P = n ! ∑ x ! E=\frac{1}{P}=\frac{n!}{\sum x!} E=P1=x!n!

由于对1e9+7取模,还要用到逆元,先算出 n ! n! n! ∑ x ! \sum x! x!,然后求 ∑ x ! \sum x! x!的逆元即可,逆元传送门这里我使用的快速幂求逆元。
注意:由于已经有序的序列我们要特判!!!
其中使用了一个C++11函数is_sorted,来判断是否有序,如果报错,请在编译选项中加入
-std=c++11
代码实现:

#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int N=1e6+5,mod=1e9+7;
ll n,tong[N],x,ans=1,sum=1,a[N];

inline ll qpow(ll a,ll b){
    
    
	a%=mod;
	ll cnt=1;
	while(b){
    
    
		if(b&1) cnt=(1ll*cnt*a)%mod;
		a=(1ll*a*a)%mod;
		b>>=1;
	}
	return cnt;
} 

int main(){
    
    
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
    
    
		scanf("%lld",&a[i]);
		ans=(1ll*ans%mod*i)%mod;
		tong[a[i]]++;
	}
	ll s=1;
	for(int i=1;i<=1e6;i++){
    
    
		sum=1;
		if(tong[i]) for(int j=1;j<=tong[i];j++)
			sum=(1ll*sum*j)%mod;
		s=(1ll*s*sum)%mod;
	}
	if(is_sorted(a+1,a+n+1)){
    
    
		cout<<0;
		return 0;
	}
	cout<<((1ll*ans*qpow(s,mod-2))%mod+mod)%mod;
	return 0;
	
}

猜你喜欢

转载自blog.csdn.net/pigonered/article/details/121183876