码迷,mamicode.com
首页 > 其他好文 > 详细

【XSY2786】Mythological VI 数学

时间:2018-03-20 20:41:56      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:多少   for   个数   string   algorithm   a*   最大   code   long   

题目描述

  有\(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 数学

标签:多少   for   个数   string   algorithm   a*   最大   code   long   

原文地址:https://www.cnblogs.com/ywwyww/p/8611973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!