NOIP模拟试题详讲2021/11/6
T1
题目大意:对于一个序列,将其随机排序,求使之单调不下降的期望。答案对1e9+7取模。
送分题,但本蒟蒻做不出来 。
首先我们来看看这个题:
求掷骰子掷到6的期望。
分析:
解法1:
对于掷了x次,就是掷到了概率为P,该次的期望次数就是1,没有掷到概率为
(
1
−
P
)
(1-P)
(1−P),由于该次没有掷到,所以期望还是E(x)
即
E
(
x
)
=
1
+
(
1
−
P
)
E
(
x
)
E(x)=1+(1-P)E(x)
E(x)=1+(1−P)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=1∑∞XiPi
如果第一次掷到了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×(1−P)P
其中概率等于上一次没有掷到6概率,乘上这一次掷6的概率。
同理,第三次掷到了6,期望为:
E
=
3
×
(
1
−
P
)
2
P
E=3\times(1-P)^2P
E=3×(1−P)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(P−1)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=i→∞limi=0∑∞(i+1)P(P−1)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;
}

浙公网安备 33010602011771号