题解




这个时候,需要枚举方程式的右边,把结果存储一下,
之后枚举方程式的左边,观察有没有对应的右边,记录最小值即可。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e7+55;
bool vis[maxn];
ll dis[maxn];
ll qpow(ll a, ll b, ll p) {
    ll ret = 1;
    while (b) {
        if (b & 1) ret = (ret * a) % p;
        b >>= 1;
        a = (a * a) % p;
    }
    return ret;
}
int main() {
    ll p, n, m;
    while (cin >> p) {
        for (int i = 0; i <= p; ++ i) {
            vis[i] = false;
        }
        ll pow3 = qpow(3ll, p-2, p);
//        cout << pow3 << endl;
        ll ret = 1;
        for (int i = 1; i <= p; ++ i) {
            ret *= pow3;
            ret %= p;
            if (!vis[ret]) {
//                cout << ret << endl;
                vis[ret] = true;
                dis[ret] = i;
            }
        }
        bool flag = false;
        ret = 1ll;
        for (int i = 0; i <= p; ++ i) {
            if (vis[ret]) {
                ll nn = i, mm = dis[ret];
                if (!flag) {
                    flag = true;
                    n = nn, m = mm;
                }
                if (nn+mm < n+m) {
                    n = nn, m = mm;
                }
                if (nn+mm == n+m && n < nn) {
                    n = nn, m = mm;
                }
            }
            ret *= 2ll;
            ret %= p;
        }
        cout << n << " " << m << endl;

    }
    return 0;
}