您的位置:首页 > 其它

FZU 2020 组合数取模(Lucas定理模版)

2016-10-18 18:46 405 查看
点击打开链接

Lucas定理证明点击打开链接

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
const int N=1e5+20;
ll quick_mod(ll a,ll b,ll p)
{
ll res=1;
while(b)
{
if(b&1)
{
res=(res*a)%p;
}
a=(a*a)%p;
b>>=1;
}
return res;
}
ll C(ll n,ll m,ll p)
{
ll a,b,r=1;
for(int i=1;i<=m;i++)//边乘边除
{
// a!/((a-b)!*b!)=(a*..a-b+1)/b!
a=(n+i-m)%p;
b=i%p;

//(a/b)%p = a*b^-1 %p p为素数用费马小求逆元
r=r*(a*quick_mod(b,p-2,p)%p)%p;
}
return r;
}
ll Lucas(ll n,ll m,ll p)
{
if(m==0)
return 1;
else
return (Lucas(n/p,m/p,p)*C(n%p,m%p,p))%p;
}
int main()
{
int t;
cin>>t;
while(t--)
{

ll n,m,p;
cin>>n>>m>>p;
//求c(n,m)%p
//c(n,m)%p=c(n/p,m/p)*c(n%p,m%p)
//证明:((1+x)^n)%p通过二项式定理考虑x^m中的系数c(n,m);
cout<<Lucas(n,m,p)<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: