数论:卢卡斯定理

#include <cstdio>
#include <cstring>
#include <vector>
#include<queue>
#include<string>
#include<iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n,m,p;
ll c[100005];//p必须为素数,且p不能太大   p<1e5
ll fastpow(ll a,ll pow,ll mod){
    
    
	long long base=a;
	long long ans=1;
	while(pow){
    
    
		if(pow&1){
    
    
			ans=(ans*base)%mod;
		}
		base=(base*base)%mod;
		pow>>=1;
	}
	return ans;
}//快速幂板子 
ll C(ll n,ll m,ll p){
    
    // 求c(n,m)%p 
	if(m>n) return 0;
	return ( (c[n]*fastpow(c[m],p-2,p) ) %p * fastpow(c[n-m],p-2,p) %p );
}//c(n,m) = n! / ( m! * (n-m)! )
ll lucas(ll n,ll m,ll p){
    
    
	if(!m) return 1;
	else{
    
    
		return ( C(n%p,m%p,p) * lucas(n/p,m/p,p) )%p;
	}//卢卡斯定理 
}
int main() {
    
    
	int t;
	scanf("%d",&t);
	while(t--){
    
    
		scanf("%lld%lld%lld",&n,&m,&p);
		c[0]=1;
		for(int i=1;i<p;++i){
    
    
			c[i]=(c[i-1]*i)%p;
		}
		printf("%lld\n",lucas(n+m,m,p));
	}
   	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45695839/article/details/109552522