zoukankan      html  css  js  c++  java
  • 古代猪文

    数论综合,考察代码能力(其实是脑子)……

    首先分析一下其实就是求一个(1)。

    略微转换一下(2)。

    因为k是n的因子,n/k是n的因子,将两个因子交换位置就可以由(1)得到(2)。

    接着就是尝试缩小计算规模的过程。

    因为999911659是个素数,由欧拉定理的推论得:(3)。

    那么我们就可以试着去求(4)。

    尝试对999911658用唯一分解定理,发现可以拆成2,3,4679,35617。

    这四个数是互质的,我们可以利用lucas定理将对2,3,4679,35617的余数分别求出,设为a1,a2,a3,a4。

    问题转化为求一个x,使之满足:

    这是一个典型的同余方程组,即:

    x是可以用CRT求解的。

    最后有了x,有了q,快速幂求一下q^x就是结果了。

    下面的代码还是不要看的好,因为求fac和inv那一段特别丑,而且交完oj缩进问题十分严重。

    有一个位置一开始打崩了,枚举因子时打成O(n)了,应该是O(sqrt(n))的,和判断素数那个思路差不多。

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #define LL long long 
    using namespace std;
    LL n,q;
    LL read(){
        LL sum=0;int f=1;char x=getchar();
        while(x<'0'||x>'9'){
            if(x=='-') f=-1;
            x=getchar();
        }while(x>='0'&&x<='9'){
            sum=sum*10+x-'0';
            x=getchar();
        }
        return sum*f;
        
    }
    LL p[6]={0,2,3,4679,35617};
    LL fac[10][50050],inv[10][50050];
    LL a[6];
    LL qpow(LL x,LL k,LL mod){
        LL ans=1;
        for(;k;k>>=1,x=x*x%mod)
            if(k&1)
                ans=ans*x%mod;
        return ans;
    }
    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*x;
        return ;
    }
    LL CRT(){
        LL ans=0,x,y;
        for(int i=1;i<=4;i++){
            exgcd(999911658/p[i],p[i],x,y);
            ans=(ans+a[i]*999911658/p[i]*x)%999911658;
        }return (ans+999911658)%999911658;
    }
    LL C(LL n,LL m,int i){
        if(m>n) return 0;
        return ((fac[i][n]*inv[i][m])%p[i])*inv[i][n-m]%p[i];
    }
    LL lucas(LL n,LL m,int i){
        if(m==0) return 1;
        return C(n%p[i],m%p[i],i)*lucas(n/p[i],m/p[i],i)%p[i];
    }
    void pre(){
        fac[1][0]=fac[2][0]=fac[3][0]=fac[4][0]=1;
        fac[1][1]=1;
        for(int i=1;i<=2;i++) fac[2][i]=fac[2][i-1]*i%p[2];
        for(int i=1;i<=4678;i++) fac[3][i]=fac[3][i-1]*i%p[3];
        for(int i=1;i<=35616;i++) fac[4][i]=fac[4][i-1]*i%p[4];
        inv[1][1]=qpow(fac[1][1],p[1]-2,p[1]);
        inv[2][2]=qpow(fac[2][2],p[2]-2,p[2]);
        inv[3][4678]=qpow(fac[3][4678],p[3]-2,p[3]);
        inv[4][35616]=qpow(fac[4][35616],p[4]-2,p[4]);
        for(int i=35616;i>=1;i--)
            inv[4][i-1]=inv[4][i]*i%p[4];
        for(int i=4678;i>=1;i--)
            inv[3][i-1]=inv[3][i]*i%p[3];
        for(int i=2;i>=1;i--)
            inv[2][i-1]=inv[2][i]*i%p[2];
        for(int i=1;i>=1;i--)
            inv[1][i-1]=inv[1][i]*i%p[1];
    
    }
    int main(){
        n=read();q=read();
        if(q%999911659==0){
            puts("0");
            return 0;
        }
        pre();
        for(int i=1;i*i<=n;i++){
            if(n%i==0){
                for(int j=1;j<=4;j++)
                    a[j]=(a[j]+lucas(n,i,j))%p[j];
                if(i*i!=n)
                    for(int j=1;j<=4;j++)
                        a[j]=(a[j]+lucas(n,n/i,j)%p[j]);
            }
        }
        LL o=CRT();
        printf("%lld
    ",qpow(q,o,999911659));
        return 0;
    }
    View Code
  • 相关阅读:
    【已解决】github中git push origin master出错:error: failed to push some refs to
    好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    THINKPHP 5.0目录结构
    thinkphp5.0入口文件
    thinkphp5.0 生命周期
    thinkphp5.0 架构
    Django template
    Django queryset
    Django model
    Python unittest
  • 原文地址:https://www.cnblogs.com/Yu-shi/p/11096222.html
Copyright © 2011-2022 走看看