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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章