Description
有(1...n)一共(n)个数。保证(n)为偶数。
小M要把这(n)个数两两配对, 一共配成(n/2)对。每一对的权值是他们两个数的和。
小M想要知道这(n)对里最大的权值的期望是多少。可怜的小M当然不知道啦,所以她向你求助。
请输出答案对(10^9+7)取模的值。
Input
一行一个正整数,表示(n)。
Output
一行一个整数,表示答案对(10^9+7)取模的值。
Sample Input
4
Sample Output
6
HINT
对于20%的数据, (nleq 10)。
对于40%的数据, (nleq 2*10^3)。
对于100%的数据, (nleq 5*10^5)。
Solution
首先可能的最大值最大为(n+(n-1)=2n-1)
考虑能不能枚举最大值(v),算出最大值等于每个(v)时的方案数,除以总方案数得到概率,再算出期望。
观察得出(vin [n+1,2n-1]),所以只要在这个区间内枚举即可。
可是考虑到计算最大值恰好等于(v)的方案数不是很可行,于是我们看看能不能转化成先求前缀和:(g[i])表示最大值小于等于(v)的方案数是多少。自然地,最大值等于(v)时的方案数为(g_v-g_{v-1})。
下面看怎么求(g_v),记(a=lfloor frac v 2
floor):
首先这(n)个数中,有些比较特别:((a,n])这些数,必须选择位于([1,a])中的数,否则最大值可能超过(v)。那就先考虑这些数的匹配方法。
先看看(n)有多少种选法:(n)必须和([1,v-n])中的数匹配,共(v-n)种选择。
(n-1)呢?必须和([1,v-(n-1)])中的数匹配,共(v-n+1)种选择;但是(n)已经从([1,v-n])挑走了一个数,所以总选择方案减1,仍然是(v-n)种选择。
由此从大到小考虑((a,n]),发现每个数的可选择方案都是(v-n),那么为((x,n])共(n-a)个数选择好匹配的总方案数为((v-n)^{n-a})。
此时([1,a])个数中已有(n-a)个数被挑走做匹配了,剩下(a-(n-a)=2a-n)个数,由于它们都小于等于(a),所以剩下的数可以任意匹配而不会出现一对数权值之和大于(v)的情况。
记(f(x))表示(x)个点任意两两匹配的方案数,推一推就得知(f(x)=f(x-2)*(x-1)),意思就是一个点从其他(x-1)个点挑一个,移除这两个点后继续操作。
则剩下的数的方案为(f(2a-n))。
所以(g_v=(v-n)^{n-a}*f(2a-n))。
总方案数是多少?可以理解为(g_{2n}),也可以理解为(f(n)),总之就是完全没有限制时的方案数。
有了(g)数组,就可以算出对于最大值为([n+1,2n-1])时的方案数,除以总方案数算出每个最大值出现的概率,最后就可以算出期望了。
#include <cstdio>
using namespace std;
const int mod=1e9+7;
const int N=500010;
int n,f[N*2],g[N*2];
inline int pow(int x,int y){
int res=1;
for(;y;x=1LL*x*x%mod,y>>=1)
if(y&1) res=1LL*res*x%mod;
return res;
}
int main(){
scanf("%d",&n);
f[0]=1;
for(int i=2;i<=n;i+=2) f[i]=1LL*f[i-2]*(i-1)%mod;
for(int v=n+1;v<=n*2;v++)
g[v]=1LL*pow(v-n,n-v/2)*f[v/2-(n-v/2)]%mod;
int ans=0;
for(int v=n+1;v<=n*2;v++)
(ans=ans+1LL*(g[v]-g[v-1])*v%mod)%=mod;
ans=1LL*ans*pow(g[n*2],mod-2)%mod;
printf("%d
",ans<0?ans+mod:ans);
return 0;
}