【Codeforces2015ICL,Finals,Div. 1#J】Ceizenpok's formula(扩展Lucas定理+中国剩余定理)

来源:互联网 发布:思迅天店软件怎么样 编辑:程序博客网 时间:2024/05/22 08:07

题目链接:https://vjudge.net/problem/Gym-100633J
题解:扩展Lucas+中国剩余定理裸题,讲解在这里:传送门

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;LL ksm(LL a,LL b,LL mod){    int ans=1;    while(b)    {        if(b&1) ans=ans*a%mod;        a=a*a%mod;        b>>=1;    }    return ans;}LL exgcd(LL a,LL b,LL &x,LL &y){    if(!b) {x=1;y=0;return a;}    else exgcd(b,a%b,y,x),y-=a/b*x;}LL inv(LL a,LL mod){    if(!a) return 0;    LL x,y;    exgcd(a,mod,x,y);    return (x%mod+mod)%mod;}LL mul(LL n,LL pi,LL pk){    if(!n) return 1ll;    LL ans=1ll;    if(n/pk)    {        for(LL i=2;i<pk;i++)            if(i%pi) ans=ans*i%pk;        ans=ksm(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*ksm(pi,k,pk)%pk;    return ans*(mod/pk)%mod*inv(mod/pk,pk)%mod;}LL exLucas(LL n,LL m,LL mod){    LL ans=0;    for(LL x=mod,i=2;i<=mod;i++)        if(x%i==0)        {            LL pk=1;            while(x%i==0) pk*=i,x/=i;            ans=(ans+C(n,m,mod,i,pk))%mod;        }    return ans; }int main(){    LL n,m,mod;    scanf("%lld%lld%lld",&n,&m,&mod);    printf("%lld\n",exLucas(n,m,mod));}
阅读全文
0 0
原创粉丝点击