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;
}