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%的数据, \(n\leq 10\)。
对于40%的数据, \(n\leq 2*10^3\)。
对于100%的数据, \(n\leq 5*10^5\)。
Solution
? 首先可能的最大值最大为\(n+(n-1)=2n-1\)
? 考虑能不能枚举最大值\(v\),算出最大值等于每个\(v\)时的方案数,除以总方案数得到概率,再算出期望。
? 观察得出\(v\in [n+1,2n-1]\),所以只要在这个区间内枚举即可。
? 可是考虑到计算最大值恰好等于\(v\)的方案数不是很可行,于是我们看看能不能转化成先求前缀和:\(g[i]\)表示最大值小于等于\(v\)的方案数是多少。自然地,最大值等于\(v\)时的方案数为\(g_v-g_{v-1}\)。
? 下面看怎么求\(g_v\),记\(a=\lfloor \frac v 2 \rfloor\):
? 首先这\(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\n",ans<0?ans+mod:ans);
return 0;
}