zoukankan      html  css  js  c++  java
  • 【BZOJ】1951[Sdoi2010]古代猪文

    【题意】给定G,N,求:

    $$ans=G^{sum_{i|n}inom{n}{i}} mod p$$

    1<=N,G<=10^9,p=999911659。

    【算法】欧拉定理+组合数取模(lucas)+中国剩余定理(CRT)

    【题解】

    先考虑简化幂运算,因为模数为素数,由欧拉定理可知G^k=G^(k%φ(p)) mod p,显然G^(k%φ(p)) mod p可以用快速幂求解

    但是欧拉定理要求(G,p)=1,当G=p时不满足条件,可以特判答案为0或者用扩展欧拉定理(b%φ(p)+(b>=φ(p)?φ(p):0))。

    故我们实际要求:

    $$sum_{i|n}inom{n}{i} mod (p-1)$$

    因为p是素数,φ(p)=p-1=999911658=2*3*4679*35617。

    因为p-1分解后无平方因子,所以直接用lucas分别对素模数计算后用中国剩余定理合并即可(若有则需要参考bzoj礼物的方法——扩展lucas)

    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=100010,MOD=999911659;//999911658=2*3*4679*35617
    const int p[5]={0,2,3,4679,35617};
    ll a[5],fac[5][maxn],n,G;
    ll power(ll x,ll k,ll p)
    {
        if(x==0)return 0;
        ll ans=1;//快速幂ans=1! 
        while(k>0)
        {
            if(k&1)ans=(ans*x)%p;//满足1时才累乘 
            x=(x*x)%p;
            k>>=1;
        }
        return ans;
    }
    ll C(ll n,ll m,ll k)
    {
        if(n<m)return 0;
        return fac[k][n]*power(fac[k][m],p[k]-2,p[k])%p[k]*power(fac[k][n-m],p[k]-2,p[k])%p[k];//n!/m!/(n-m)!
    }    
    ll lucas(ll n,ll m,ll k)
    {
        if(n<m)return 0;
        if(n<p[k]&&m<p[k])return C(n,m,k);
        return C(n%p[k],m%p[k],k)*lucas(n/p[k],m/p[k],k)%p[k];
    }
    int main()
    {
        scanf("%lld%lld",&n,&G);
        if(G==MOD)
        {
            printf("0");
            return 0;
        }
        for(int k=1;k<=4;k++)
        {
            fac[k][0]=1;
            for(int i=1;i<p[k];i++)fac[k][i]=fac[k][i-1]*i%p[k];//随时记得取模 
        }
        for(int i=1;i*i<=n;i++)if(n%i==0)
        {
            int j=n/i;
            for(int k=1;k<=4;k++)
            {
                a[k]=(a[k]+lucas(n,i,k))%p[k];
                if(i!=j)a[k]=(a[k]+lucas(n,j,k))%p[k];
            }
        }
        ll M=MOD-1;
        ll ans=0;
        for(int k=1;k<=4;k++)ans=(ans+a[k]*M/p[k]*power(M/p[k],p[k]-2,p[k]))%M;
        printf("%lld",power(G,ans,MOD));
        return 0;
    }
    View Code
  • 相关阅读:
    常见寻找OEP脱壳的方法
    Windows内核原理系列01
    HDU 1025 Constructing Roads In JGShining's Kingdom
    HDU 1024 Max Sum Plus Plus
    HDU 1003 Max Sum
    HDU 1019 Least Common Multiple
    HDU 1018 Big Number
    HDU 1014 Uniform Generator
    HDU 1012 u Calculate e
    HDU 1005 Number Sequence
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7196029.html
Copyright © 2011-2022 走看看