2020.7.4 -- BSGS算法

数论BSGS算法

求解 满足 a^x = b (mod p) 的最小自然数x
模板

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 13331;
ll a, b, p, ans;

ll qpow(ll a, ll b, ll mod = 1e9 + 7)
{
    if (b < 0)
        return 0;
    ll ret = 1;
    a %= mod;
    while (b)
    {
        if (b & 1)
            ret = (ret * a) % mod;
        b >>= 1;
        a = (a * a) % mod;
    }
    return ret;
}
ll inv(ll a)
{
    int mo = p;
    return qpow(a, mo - 2, mo);
}
ll Bsgs(ll a, ll b, ll p)
{ // a ^ x ≡ b(mod p)
    map<ll, ll> hash;
    hash.clear();
    b %= p;
    int t = (int)sqrt(p) + 1;
    for (int j = 0; j < t; j++)
    {
        ll val = b * qpow(a, j, p) % p;
        hash[val] = j;
    }
    a = qpow(a, t, p);
    if (a == 0)
        return b == 0 ? 1 : -1;
    for (ll i = 0; i <= t; i++)
    {
        ll val = qpow(a, i, p);
        ll j = hash.find(val) == hash.end() ? -1 : hash[val];
        if (j >= 0 && i * t - j >= 0)
            return i * t - j;
    }
    return -1;
}
void solve1()
{
    while (~scanf("%lld%lld%lld", &a, &b, &p))
    {
        cout << qpow(a, b, p) << endl;
    }
}
void solve2()
{
    while (~scanf("%lld%lld%lld", &a, &b, &p))
    {
        if (a % p == 0)
            cout << "Orz, I cannot find x!" << endl;
        else
        {
            a = inv(a);
            // cout << inv(a) << endl;
            cout << (a * b) % p << endl;
        }
    }
}
void solve3()
{
    while (~scanf("%lld%lld%lld", &a, &b, &p))
    {
        ans = Bsgs(a, b, p);
        ans == -1 ? puts("Orz, I cannot find x!") : printf("%lld\n", ans);
    }
}
int main()
{
    int t, k;
    cin >> t >> k;
    if (k == 1)
        solve1();
    else if (k == 2)
        solve2();
    else
        solve3();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值