luoguP4720 【模板】扩展卢卡斯

www.cnblogs.com/shaokele/


luoguP4720 【模板】扩展卢卡斯##

  Time Limit: 1 Sec
  Memory Limit: 256 MB

Description###

  求 $$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);
}
原文地址:https://www.cnblogs.com/shaokele/p/9298959.html