大胆猜结论:k^x≡1 mod m,答案就是最小正x
直接EXBSGS套上,明显最小解为0,所以答案是次小解,虽然我总觉得我的是错的但它就是过了……
EXBSGS盗的某位大爷的板
#include<math.h>
#include<stdio.h>
#include<string.h>
#include <iostream>
#include<algorithm>
#define N 140142
using namespace std;
typedef long long ll;
struct Hash_Set
{
ll head[N], next[N], X[N], val[N], tot;
void clear()
{
memset(head, 0, sizeof(head));
memset(next, 0, sizeof(next));
memset(val, -1, sizeof(val));
memset(X, 0, sizeof(X));
tot = 0;
}
ll& operator [](ll x)
{
ll index = x%N;
for (ll i = head[index]; i; i = next[i])
{
if (X[i] == x)
return val[i];
}
next[++tot] = head[index];
head[index] = tot;
X[tot] = x;
return val[tot];
}
}hash;
ll pow(ll x, ll y, ll mod)
{
ll ret = 1;
while (y)
{
if (y & 1)
ret = ret*x%mod;
x = x*x%mod;
y >>= 1;
}
return ret;
}
ll gcd(ll a, ll b)
{
ll t = a%b;
while (t)
{
a = b, b = t;
t = a%b;
}
return b;
}
void exgcd(ll a, ll b, ll &x, ll &y)
{
if (!b)
x = 1, y = 0;
else
{
exgcd(b, a%b, y, x);
y -= a / b*x;
}
}
ll inv(ll t, ll mod)
{
ll x, y;
exgcd(t, mod, x, y);
return (x%mod + mod) % mod;
}
ll BSGS(ll A, ll B, ll C)
{
hash.clear();
ll bk = ceil(sqrt(C)), i, j, k, D, temp;
for (i = 0, D = 1; i < bk; i++, D = D*A%C)
{
if (hash[D] == -1)
hash[D] = i;
}
temp = inv(D, C);
bool fg = 0;
for (i = 0, k = B; i <= bk; i++, k = k*temp%C)
{
if (hash[k] != -1) {
if(!fg) {
fg = 1;
}
else return i*bk + hash[k];
}
}
return -1;
}
ll EXBSGS(ll A, ll B, ll C)
{
if(C==1)
{
if(!B) return 0;
else return -1;
}
ll lg = ceil(log(C*1.0) / log(2)), i, k, mod;
for (i = 0, k = 1; i <= lg; i++, k = k*A%C);
i = 0, mod = C;
while ((k = gcd(A, mod)) != 1)
{
if (B%k) return -1;
B /= k, mod /= k;
i++;
}
ll ret = BSGS(A, B*inv(pow(A, i, mod)*inv(C / mod, mod) % mod, mod) % mod, mod);
if (ret != -1)
return ret + i;
else
return -1;
}
int main()
{
ll A, C;
cin >> C >> A;
ll ans = EXBSGS(A, 1, C);
if(ans >= 0) cout << ans;
else puts("Let's go Blue Jays!");
return 0;
}