www.cnblogs.com/shaokele/
luoguP4720 【模板】扩展卢卡斯##
Time Limit: 1 Sec
Memory Limit: 256 MBDescription###
求 $$C_{n}^{m} mod p$$
其中 (C) 为组合数。
Input###
一行三个整数 (n,m,p) ,含义由题所述。
Output###
一行一个整数,表示答案。
Sample Input 1###
5 3 3
Sample Output 1###
1
Sample Input 1###
666 233 123456
Sample Output 1###
61728
HINT###
(1≤m≤n≤ 10^{18} ,2≤p≤1000000) ,不保证 (p) 是质数。
题目地址: luoguP4720 【模板】扩展卢卡斯
题目大意: 题目已经很简洁了>_<
题解:
模板题
AC代码
#include <cstdio>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
ll n,m,MOD,ans;
ll fast_pow(ll x,ll e,ll Mod){
ll res=1ll;
while(e){
if(e&1)res=res*x%Mod;
x=x*x%Mod;
e>>=1;
}
return res;
}
void exgcd(ll a,ll b,ll &x,ll &y){
if(!b)x=1ll,y=0ll;
else exgcd(b,a%b,y,x),y-=a/b*x;
}
ll inv(ll A,ll Mod){
if(!A)return 0ll;
ll a=A,b=Mod,x=0ll,y=0ll;
exgcd(a,b,x,y);
x=((x%b)+b)%b;
if(!x)x+=b;
return x;
}
ll Mul(ll n,ll pi,ll pk){
if(!n)return 1ll;
ll ans=1ll;
for(ll i=2;i<=pk;++i)
if(i%pi)ans=ans*i%pk;
ans=fast_pow(ans,n/pk,pk);
for(ll i=2;i<=n%pk;++i)
if(i%pi)ans=ans*i%pk;
return ans*Mul(n/pi,pi,pk)%pk;
}
ll C(ll n,ll m,ll Mod,ll pi,ll pk){
if(m>n)return 0ll;
ll a=Mul(n,pi,pk),b=Mul(m,pi,pk),c=Mul(n-m,pi,pk);
ll k=0ll,ans;
for(ll i=n;i;i/=pi)k+=i/pi;
for(ll i=m;i;i/=pi)k-=i/pi;
for(ll i=n-m;i;i/=pi)k-=i/pi;
ans=a*inv(b,pk)%pk*inv(c,pk)%pk*fast_pow(pi,k,pk)%pk;
return ans*(Mod/pk)%Mod*inv(Mod/pk,pk)%Mod;
}
int main(){
scanf("%lld%lld%lld",&n,&m,&MOD);
for(ll x=MOD,i=2;i<=MOD;++i)
if(x%i==0){
ll pk=1ll;
while(x%i==0)pk*=i,x/=i;
ans=(ans+C(n,m,MOD,i,pk))%MOD;
}
printf("%lld
",ans);
}