弱校联盟#con3--概率(阶乘逆元打表)

来源:互联网 发布:淘宝童装店铺简介 编辑:程序博客网 时间:2024/06/08 07:39

List’s father morejarphone likes playing poker with List very much. Now List has a deck of playing card, consisting of a black cards and b red cards. List shuffles the cards randomly, puts them on the desk and tells morejarphone to do the following operations:
1. taking away one card randomly;
2. checking the color of it, if it is black, repeats the operations until he take a red one or there are no cards left, else stops.
Now List wants to know the mathematical expectation of the cards morejarphone takes away in total. To avoid the float number, you should multiply the answer by (a+b)! then mod 1e9+7. If morejarphone can’t take red card, output “List, are you kidding me?”.

%mod*A会先算乘呀。。我好智障啊。。。wa了那么多个小时???
博客里还没有逆元啊。。随便说一句。。
费马小定理知道a^(p-1) = 1(mod p)(p为素数)
那么a的逆元一定a^(p-2) 除非再mod下先后顺序不能改变,否则影响结果
然后阶乘逆元是前面的逆元乘起来 那从后往前退,就是
inv[n] = inv[(n+1)!]/inv[n+1] = inv[(n+1)!]*(n+1)

还有单纯递推逆元的话,不用每一个都快速幂求p-2次幂。。

void init(){    inv[1]=1;      for(int i=2; i<N; i++)          inv[i]=(mod-mod/i)*inv[mod%i]%mod;     }
#include <cstdio>#include <iostream>#include <cstring>using namespace std;typedef long long LL;const LL MOD = 1e9+7;const int maxn = 1e6+10;int T;LL inv[maxn],Fac[maxn];LL quipow(LL m,LL nn){    LL ans = 1;    while (nn){        if (nn & 1)            ans = (ans*m) % MOD;        m = (m * m) % MOD;        nn >>= 1;    }    return ans;}void init(){    Fac[1] = 1;    Fac[0] = 1;    LL maxx = 1e6+2;    for(int i = 2;i <= maxx;i++){        Fac[i] = (Fac[i-1]*(long long)i)%MOD;    }    inv[maxx]=quipow(Fac[maxx],MOD-2);    for(int i = maxx-1;i >= 0;i--){        inv[i]=(inv[i+1]*(long long)(i+1))% MOD;    }    //cout << inv[0]<<endl;}void sov(){    for(int i = 1; i <= T ; i++){        long long  A,B;        cin >>A >> B;        printf("Case #%d:",i);        if(B == 0){            printf(" List, are you kidding me?\n");            continue;        }        LL ans = (B * Fac[A+B-1]) % MOD ;        for ( LL k = 1 ; k <= A ; k ++ ) {            LL tmp = (B * Fac[A+B-k-1]) % MOD ;            tmp = (tmp * Fac[A]) % MOD ;            tmp = (tmp * inv[A-k]) % MOD ;            tmp = (tmp * (k+1)) % MOD ;            ans = (ans + tmp) % MOD ;        }        cout <<" "<<ans<<endl;    }}int main(){    init();    scanf("%d",&T);    sov();    return 0;}
0 0
原创粉丝点击