卢卡斯定理
卢卡斯定理是用来求组合数取模的一种log级别的算法。
Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)
至于组合数怎么求可以参考逆元博客。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define il inline
#define db double
using namespace std;
int k,n,m,p;
ll a[100045],b[100045];
ll luca(int x,int y)
{
if(x<y)
return 0;
else
if(x<p)
return b[x]*a[y]*a[x-y]%p;
else
return luca(x/p,y/p)*luca(x%p,y%p)%p;
}
int main()
{
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
scanf("%d%d%d",&n,&m,&p);
a[0]=a[1]=b[0]=b[1]=1;
for(int i=2;i<=n+m;i++)
a[i]=(p-p/i)*a[p%i]%p,b[i]=b[i-1]*i%p;
for(int i=2;i<=n+m;i++)
a[i]=a[i-1]*a[i]%p;
printf("%lld\n",luca(n+m,m));
}
return 0;
}
PEACE

浙公网安备 33010602011771号