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;
}