卢卡斯定理 Lucas
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了卢卡斯定理 Lucas相关的知识,希望对你有一定的参考价值。
参考文章
详细定义内容看这个参考文章
结论:
模板:
Lucas函数:
long long Lucas(long long n,long long m){
if(m==0) return 1;
return Lucas(n/p,m/p)*C(n%p,m%p)%p;
}
组合数函数:
此处求逆元的用的bp-2
long long C(long long n,long long m){
if(n<m) return 0;
if(m>n-m) m=n-m;
long long a=1,b=1;
for(int i=0;i<m;i++){
a=(a*(n-i))%p;
b=(b*(i+1))%p;
}
return a*quickpow(b,p-2)%p;
}
整体代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
long long n,m,p;
long long quickpow(long long base,long long power){
long long ret=1;
while(power){
if(power%2)
ret=ret*base%p;
base=base*base%p;
power/=2;
}
return ret;
}
long long C(long long n,long long m){
if(n<m) return 0;
if(m>n-m) m=n-m;
long long a=1,b=1;
for(int i=0;i<m;i++){
a=(a*(n-i))%p;
b=(b*(i+1))%p;
}
return a*quickpow(b,p-2)%p;
}
long long Lucas(long long n,long long m){
if(m==0) return 1;
return Lucas(n/p,m/p)*C(n%p,m%p)%p;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%lld%lld%lld",&n,&m,&p);
printf("%lld\\n",Lucas(n,m));
}
return 0;
}
复杂度
O(p * logm * logp),后者都是常数级别,所以复杂度主要取决于p,p不能太大,一般在105以内即可
优化
由于p已知,所以可以O§的处理阶乘,优化常数
以上是关于卢卡斯定理 Lucas的主要内容,如果未能解决你的问题,请参考以下文章