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\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/shaokele/p/9298959.html
今日推荐