zoukankan      html  css  js  c++  java
  • 离散对数

    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    //返回a*b%n,要求0<=a,b<n 
    ll mul_mod(ll a,ll b,ll n){
        return a*b%n; 
    }
    //返回a^p%n,要求0<=a<n 
    ll pow_mod(ll a,ll p,ll n)
    {   
        ll ans=1;  
        while(p>0){  
            if(p&1) ans=(ans*a)%n;  
            a=(a*a)%n;  
            p>>=1;  
        }  
        return ans;
    }
    //扩展欧几里得算法 
    void gcd(ll a,ll b,ll &d,ll &x,ll &y)
    {
        if(!b){
            d=a;
            x=1,y=0;
        }
        else{
            gcd(b,a%b,d,y,x);
            y-=(a/b)*x;
        }
    } 
    //计算模n下a的逆,如果不存在逆,返回-1 
    ll inv(ll a,ll n)
    {
        ll d,x,y;
        gcd(a,n,d,x,y);
        return d==1?(x+n)%n:-1;
    }
    //求解模方程a^x=b(mod n)n为素数。无解返回-1 
    ll log_mod(ll a,ll b,ll n)
    {
        ll e=1;
        ll m=(ll)sqrt(n+0.5);
        ll v=inv(pow_mod(a,m,n),n);
        map<ll,ll> x;
        x[1]=0;
        for(ll i=1;i<m;i++){
            e=mul_mod(e,a,n);
            if(!x.count(e)) x[e]=i;
        }
        for(ll i=0;i<m;i++){
            if(x.count(b)) return i*m+x[b];
            b=mul_mod(b,v,n);
        }
        return -1;
    } 
    int main()
    {
        ll a,b,n;
        scanf("%lld%lld%lld",&a,&b,&n);
        printf("%lld",log_mod(a,b,n));
    }
  • 相关阅读:
    泰勒综合
    滤波器、窗等的系数为什么是对称的?
    l'alphabet en francais
    弄清for循环的本质
    js中的闭包
    js中用正则表达式
    java Calendar
    Android实现XML解析技术
    junit4 详解
    redhat vi 命令
  • 原文地址:https://www.cnblogs.com/freinds/p/6406021.html
Copyright © 2011-2022 走看看