lucas定理求组合数

定理及其推导由于符号书写不方便,我就写在纸上了(累死)

给定 n 组询问,每组询问给定三个整数 a,b,p,其中 p 是质数,请你输出 C(a,b)modp 的值。

输入格式

第一行包含整数 n

接下来 n 行,每行包含一组 a,b,p

输出格式

共 n 行,每行输出一个询问的解。

数据范围

1n20
1ba10^18
1p10^5

输入样例:

3
5 3 7
3 1 5
6 4 13

输出样例:

3
3
2

#include<bits/stdc++.h> 
using namespace std;
const int N=100002;
long long a,b;
int p;
long long qmi(long long a,long long b,int p)
{
    long long ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a%p;
        a=a*a%p;
        b>>=1;
    }
    return ans;
}
long long C(long long a,long long b,int p)
{
    if(b>a) return 0;
    long long ans=1;
    for(int i=1,j=a;i<=b;i++,j--)
    {
        ans=ans*j%p;
        ans=ans*qmi(i,p-2,p)%p;
    }
    return ans;
}
long long lucas(long long a,long long b,int p)
{
    if(a<p&&b<p) return C(a,b,p);
    return  C(a%p,b%p,p)*lucas(a/p,b/p,p)%p;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        cin>>a>>b>>p;
        printf("%lld\n",lucas(a,b,p));
    }
    return 0;
}

希望大家能够喜欢!



posted @ 2021-05-05 21:40  AC--Dream  阅读(63)  评论(0编辑  收藏  举报