ll BSGS(ll a, ll b, const ll p)// 离散对数 { if (1LL % p == b % p) return0; // 特判0 ll t = std::sqrt(p) + 1; std::map<ll, ll> mp; ll d = 1; // a^t for (int i = 0; i < t; ++i) { mp[b * d % p] = i; // 可以直接覆盖,如果有重复的会取更大的,这样At - B就是最小的 d = d * a % p; } a = 1; for (int i = 1; i <= t; ++i) { a = a * d % p; if (mp.count(a)) // 存在 return i * t - mp[a]; } return -INF; // 无解 }
ll BSGS(ll a, ll b, const ll p, ll k = 1LL)// k是多加的系数 { if (k % p == b % p) // 特判0 return0; ll t = std::sqrt(p) + 1; std::map<ll, ll> mp; ll d = 1; for (int i = 0; i < t; ++i) { mp[b * d % p] = i; d = d * a % p; } a = k; // 正常这里是1,加了系数所以是k for (int i = 1; i <= t; ++i) { a = a * d % p; if (mp.count(a)) return i * t - mp[a]; } return -INF; // 无解 } ll exBSGS(ll a, ll b, ll p) { ll k = 1; // k是系数 for (int i = 0;; ++i) { if (k % p == b % p) // 迭代中特判0 return i; ll gcd = std::gcd(a, p); if (b % gcd) return -INF; // 无解 if (gcd == 1) returnBSGS(a, b, p, k) + i; k = k * a / gcd % p, b /= gcd, p /= gcd; } }