1. 程式人生 > >【XSY2786】Mythological VI 數學

【XSY2786】Mythological VI 數學

取模 -m pen urn turn isp div 輸出 時間復雜度

題目描述

  有\(1\sim n\)一共\(n\)個數。保證\(n\)為偶數。

  你要把這\(2n\)個數兩兩配對,一共配成\(n\)對。每一對的權值是他們兩個數的和。

  你想要知道這\(n\)對裏最大的權值的期望是多少。

  請輸出答案對\(1000000007\)取模的值。

  \(n\leq 500000\)

題解

  枚舉\(v\),計算最大權值\(\leq v\)的概率。

  從大到小枚舉\(> \frac{v}{2}\)的數,這些數每次都有\(v-n\)種選擇,方案數為
\[ {(v-n)}^{n-\frac{v}{2}} \]
  \(\leq \frac{v}{2}\)的數可以隨便匹配。

  記\(f(x)\)

\(x\)個數隨便匹配的方案數,那麽
\[ f(x)=\frac{x!}{2^{\frac{x}{2}}(\frac{x}{2})!} \]
  (考慮\(x\)的全排列,\(a_{2i-1}\)\(a_{2i}\)匹配。)

  時間復雜度:\(O(n\log n)\)

代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll p=1000000007;
ll fp(ll a,ll b)
{
    ll s=1
; for(;b;b>>=1,a=a*a%p) if(b&1) s=s*a%p; return s; } ll f[500010]; ll g[1000010]; int main() { #ifndef ONLINE_JUDGE freopen("b.in","r",stdin); freopen("b.out","w",stdout); #endif int n; scanf("%d",&n); ll ans=0
; f[0]=1; for(int i=2;i<=n;i+=2) f[i]=f[i-2]*(i-1)%p; for(int i=n+1;i<=2*n;i++) g[i]=fp(i-n,n-i/2)*f[n-2*(n-i/2)]%p; for(int i=2*n;i>=n+1;i--) g[i]=(g[i]-g[i-1])%p; for(int i=n+1;i<=2*n;i++) ans=(ans+g[i]*i)%p; ans=ans*fp(f[n],p-2)%p; ans=(ans+p)%p; printf("%lld\n",ans); return 0; }

【XSY2786】Mythological VI 數學