洛谷 P3834 卢卡斯定理 题解

题面

首先你需要知道这条定理:

C(n,m)=C(n%p,m%p)*C(n/p,m/p);

这样可以递归实现;

注意坑点:是C(n+m,m),并不是C(n,m);

#include <bits/stdc++.h>
using namespace std;
long long n,m,p;
inline long long KSM(long long a,long long b)
{
    long long res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b/=2;
    }
    return res%p;
}
long long C(long long n,long long m)
{
    if(n<m) return 0; //并不是返回1;
    long long res1=1,res2=1;
    for(register int i=(n-m+1);i<=n;i++){
        res1=res1*i%p;
    }
    for(register int i=1;i<=m;i++){
        res2=res2*i%p;
    }
    return res1*KSM(res2,p-2)%p;
}
long long LUCAS(long long n,long long m)
{
    if(m==0){
        return 1;  
    }
    return C(n%p,m%p)*LUCAS(n/p,m/p)%p;
}
int main ()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m>>p;
        cout<<LUCAS(n+m,m)<<endl;
    }
}
原文地址:https://www.cnblogs.com/kamimxr/p/11314923.html