zoukankan      html  css  js  c++  java
  • 一道诡异的考试题

    题目:

      给定$a$张黑牌,$b$白牌,甲,乙两人按以下顺序抽牌:

      甲抽一张,乙抽一张,然后弃去一张,然后重复以上过程。

      先抽到黑牌者胜,求甲和乙获胜的概率$mod 1004535809$的值。

    输入:

      一行,两个整数$a b$,分别代表黑牌张数和白牌张数

    输出:

      一行,两个整数,分别代表甲和乙的胜率

    数据范围:

      $a,bleq10000$

    样例:

      

    考试之后题解给的是这样的:

     然而在我们的电脑上,它T了,然后巨佬renhr想出了以下方法//%%% renhr!!!!

    一句微小的提示:以下各式子中除法默认向下取整。

    先考虑平局的情况,这种情况下一定是黑牌全部被弃去,因此其概率为:

      [frac{{C_{{ extstyle{{a + b} over 3}}}^a}}{{C_{a + b}^a}}]

    接下来考虑甲胜的情况:

      我们枚举在第几局决出胜负,那么在这一局之前,甲乙二人抓到的一定是白牌,在这一局,甲抓到了黑牌,不妨设这是第$i$局,那么将会有$a+b-2*i-3$个位置上的牌的颜色是不确定的,而这些位置上有共计$a-1$张黑牌,因而甲的胜率为:

       [frac{{sumlimits_{i = 1}^{{ extstyle{{a + b} over 3}}} {C_{a + b - 2i - 3}^{a - 1}} }}{{C_{a + b}^a}}]

    接下来容斥一下,就能得到乙的胜率了。

    组合数用线筛逆元即可。

    本蒟蒻的代码:跑的比标程快的多

    #include<cstdio>
    #define mod 1004535809ll
    int a,b,n;
    long long pin[20100],inv[20100],fw,lw;
    void init()
    {
        pin[0]=1;
        for(int i=1;i<=20010;i++)
            pin[i]=pin[i-1]*i%mod;
        inv[0]=1;
        inv[1]=1;
        for(int i=2;i<=20010;i++)
            inv[i]=(mod-mod/i)*inv[mod%i]%mod;
        for(int i=2;i<=20010;i++)
            inv[i]=inv[i-1]*inv[i]%mod;
    }
    long long C(int x,int y)
    {
        if(x<y||x<0||y<0)
            return 0;
        return pin[x]*inv[y]%mod*inv[x-y]%mod;
    }
    int main()
    {
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
        init();
        scanf("%d%d",&a,&b);
        n=a+b;
        for(int i=1;i<=n;i+=3)
        {
            fw=(fw+C(n-2*i/3-1,a-1))%mod;
        }
        long long bas=inv[n]*pin[b]%mod*pin[a]%mod;
        long long draw=C(n/3,a)*bas%mod;
        fw=fw*bas%mod;
        lw=(1-draw-fw+2*mod)%mod;
        printf("%lld %lld
    ",fw,lw);
        return 0;
    }

      

  • 相关阅读:
    [BUUCTF]PWN3——warmup_csaw_2016
    分页
    关系与外键约束
    连接查询
    自关联
    子查询
    视图
    事务
    索引
    绘图笔记
  • 原文地址:https://www.cnblogs.com/Grharris/p/11770938.html
Copyright © 2011-2022 走看看