zoukankan      html  css  js  c++  java
  • exlucas

    exlucas

    P4720 【模板】扩展卢卡斯

    模板代码来自这位大佬https://www.cnblogs.com/yyys-/p/11311858.html

    #include <cstdio>
    #define LL long long
    using namespace std;
    LL quick(LL a,LL x,LL p)
    {
        LL ans=1;
        while(x)
        {
            if(x&1) ans=ans*a%p;
            a=a*a%p;x>>=1;
        }
        return ans%p;
    }
    void exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b){x=1,y=0;return;}
        exgcd(b,a%b,x,y);
        LL t=x;
        x=y;y=t-(a/b)*y;
    }
    LL inv(LL a,LL b)
    {
        LL x,y;
        exgcd(a,b,x,y);
        return (x%b+b)%b;
    }
    LL fac(LL n,LL x,LL p)
    {
        if(!n) return 1;
        LL ans=1;
        for(LL i=1;i<=p;++i)
          if(i%x)ans=ans*i%p;//不含因子x
        ans=quick(ans,n/p,p);//有循环节,所以乘积用快速幂计算即可(整块的)
        for(LL i=1;i<=n%p;i++)//未构成整块的
          if(i%x)
            ans=ans*i%p;
        return ans*fac(n/x,x,p)%p;//当前的不含因子x的乘积乘以递归下去求的剩余阶乘部分的结果
    }
    LL cal(LL n,LL m,LL x,LL p)//x是当前质数,p是题目要求质数
    {
        LL N=fac(n,x,p),M=fac(m,x,p),Z=fac(n-m,x,p);
        //计算出对于每一个质数的若干次方取模后的结果
        LL cnt=0;
        for(LL i=n;i;i/=x)
          cnt+=i/x;
        for(LL i=m;i;i/=x)
          cnt-=i/x;
        for(LL i=n-m;i;i/=x)
          cnt-=i/x;
        LL ans=quick(x,cnt,p)*N%p*inv(M,p)%p*inv(Z,p)%p;
        return ans%p;
    }
    LL CRT(LL a,LL p,LL x)
    {
        return inv(p/x,x)*(p/x)%p*a%p;
    }
    LL exlucas(LL n,LL m,LL p)
    {
        LL t=p,ans=0;
        for(LL i=2;i*i<=p;++i)
        {
            LL k=1;
            if(t%i)continue;
            while(t%i==0){k=k*i;t=t/i;}
            ans=(ans+CRT(cal(n,m,i,k),p,k))%p;
        }
        if(t>1)ans=(ans+CRT(cal(n,m,t,t),p,t))%p;
        return ans%p;
    }
    int main()
    {
        LL n, m, p;
        scanf("%lld %lld %lld", &n, &m, &p);
        printf("%lld
    ", exlucas(n,m,p));
        return 0;
    }
    

    P2183 [国家集训队]礼物

    也算模板题吧

    #include <cstdio>
    #define LL long long
    using namespace std;
    LL quick(LL a,LL x,LL p)
    {
        LL ans=1;
        while(x)
        {
            if(x&1) ans=ans*a%p;
            a=a*a%p;x>>=1;
        }
        return ans%p;
    }
    void exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b){x=1,y=0;return;}
        exgcd(b,a%b,x,y);
        LL t=x;
        x=y;y=t-(a/b)*y;
    }
    LL inv(LL a,LL b)
    {
        LL x,y;
        exgcd(a,b,x,y);
        return (x%b+b)%b;
    }
    LL fac(LL n,LL x,LL p)
    {
        if(!n) return 1;
        LL ans=1;
        for(LL i=1;i<=p;++i)
          if(i%x)ans=ans*i%p;//不含因子x
        ans=quick(ans,n/p,p);//有循环节,所以乘积用快速幂计算即可(整块的)
        for(LL i=1;i<=n%p;i++)//未构成整块的
          if(i%x)
            ans=ans*i%p;
        return ans*fac(n/x,x,p)%p;//当前的不含因子x的乘积乘以递归下去求的剩余阶乘部分的结果
    }
    LL cal(LL n,LL m,LL x,LL p)//x是当前质数,p是题目要求质数
    {
        LL N=fac(n,x,p),M=fac(m,x,p),Z=fac(n-m,x,p);
        //计算出对于每一个质数的若干次方取模后的结果
        LL cnt=0;
        for(LL i=n;i;i/=x)
          cnt+=i/x;
        for(LL i=m;i;i/=x)
          cnt-=i/x;
        for(LL i=n-m;i;i/=x)
          cnt-=i/x;
        LL ans=quick(x,cnt,p)*N%p*inv(M,p)%p*inv(Z,p)%p;
        return ans%p;
    }
    LL CRT(LL a,LL p,LL x)
    {
        return inv(p/x,x)*(p/x)%p*a%p;
    }
    LL exlucas(LL n,LL m,LL p)
    {
        LL t=p,ans=0;
        for(LL i=2;i*i<=p;++i)
        {
            LL k=1;
            if(t%i)continue;
            while(t%i==0){k=k*i;t=t/i;}
            ans=(ans+CRT(cal(n,m,i,k),p,k))%p;
        }
        if(t>1)ans=(ans+CRT(cal(n,m,t,t),p,t))%p;
        return ans%p;
    }
    int main() {
        LL p, n, m, sum = 0, a[10];
        scanf("%lld %lld %lld", &p, &n, &m);
        for(int i = 0; i < m; i++) {
            scanf("%lld", &a[i]);
            sum += a[i];
        }
        if(sum > n) printf("Impossible
    ");
        else {
            LL ans = 1;
            sum = 0;
            for(int i = 0; i < m; i++) {
                ans = ans * exlucas(n - sum, a[i], p) % p;
                sum += a[i];
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS NSDictionary或NSArray与JSON字符串相互转换
    iOS 如何用Xib画一个Button
    iOS 你不知道的字符串用法
    IOS ScrollView pagingEnabled移动指定偏移
    TableView行缩进 自定义cell时候
    支付宝回调
    微信支付回调
    关于Bundle传递消息
    关于Handler
    ExpandableListView
  • 原文地址:https://www.cnblogs.com/fanshhh/p/12641815.html
Copyright © 2011-2022 走看看