Baby-step-Giant-step(北上廣深)之 Discrete Logging POJ - 2417

Baby-step-Giant-step:

Baby-step-Giant-step算法,又叫北上廣深算法,拔山蓋世算法,大步小步算法。。。。

 

面向問題:

已知A, B, C,求X使得 A^x = B (mod C)(C爲素數)

 

設m = sqrt(C)上取整, x = i*m + j, 那麼 A^x = (A^m)^i  *  A^j, (0<=i , j< m),然後可以枚舉i,這是一個sqrt(C)級別的枚舉

 

一道BSGS模板題:Discrete Logging POJ - 2417

 

黑洞內窺:

、給出P , B , N , 求一個整數L,使得它滿足 B ^ L == N (mod P)

 

思維光年:

BSGS模板

 

ACcode;

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
//#include      <map>
//#include      <set>
//#include   <vector>
//#include    <queue>
//#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
using namespace std;
typedef long long ll;
#define MAXN 45689
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
const ll mod = 1000000007;

bool Hash[MAXN];
ll j[MAXN], val[MAXN];

void Insert(ll jj, ll vv)  				//插入哈希表
{
    ll v = vv % MAXN;
    while (Hash[v] && val[v] != vv)
    {
        v++;
        if (v == MAXN)
            v -= MAXN;
    }
    if (!Hash[v])
    {
        Hash[v] = 1;
        j[v] = jj;
        val[v] = vv;
    }
}

int found(ll vv)  					//查找vv對應的jj,A^jj = vv
{
    ll v = vv % MAXN;
    while (Hash[v] && val[v] != vv)
    {
        v++;
        if (v == MAXN)
            v -= MAXN;
    }
    if (Hash[v] == 0)
        return -1;
    return j[v];
}

ll exgcd(ll a, ll b, ll &x, ll &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    ll gcd = exgcd(b, a%b, x, y);
    ll tem = x;
    x = y;
    y = tem - a / b * y;
    return gcd;
}

ll BSGS(ll A, ll B, ll C)
{
    for (int i = 0; i <= MAXN; ++i)
        Hash[i] = 0, val[i] = j[i] = 0;
    ll M = ceil(sqrt(C*1.0)); //將A^j存入Hash表中
    ll D = 1;
    for (int j = 0; j < M; ++j)
    {
        Insert(j, D);
        D = D * A%C;
    }
    ll res = 1, x, y;
    for (int i = 0; i < M; ++i)
    {
        exgcd(res, C, x, y);
        x = x * B;
        x = (x%C + C) % C;
        int j = found(x);
        if (j != -1)
            return (ll)i*M + j;
        res = res * D%C;
    }
    return -1;
}

int main()
{
    ll A, B, C;
    while (cin >> A >> B >> C)
    {
        ll x = BSGS(B, C, A);
        if (x == -1)
            puts("no solution");
        else
            cout << x << '\n';
    }
    return 0;
}

 

發佈了165 篇原創文章 · 獲贊 35 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章