「解题报告」ARC158D Equation

好神仙的题。

考虑形如 \(F(x, y, z) = x^i + y^i + z^i\) 的函数有一个性质:\(F(tx, ty, tz) = t^i F(x, y, z)\)

原式要求 \((x+y+z)(x^n+y^n+z^n)(x^{2n}+y^{2n}+z^{2n})\equiv x^{3n}+y^{3n}+z^{3n}\),假如我们令 \(x = ta, y = tb, z = tc\),那么有 \(t^{3n+1}(a+b+c)(a^n+b^n+c^n)(a^{2n}+b^{2n}+c^{2n})\equiv t^{3n}(a^{3n}+b^{3n}+c^{3n})\)

那么假如我们有一个 \((a, b, c)\),满足 \((a+b+c)(a^n+b^n+c^n)(a^{2n}+b^{2n}+c^{2n}) \ne 0\)\(a^{3n}+b^{3n}+c^{3n}\),那么我们就能计算出 \(t\),那么 \((x, y, z) = (ta, tb, tc)\) 就是一组答案。

我们可以每次随机 \((a, b, c)\),然后判定答案合不合法即可。

我们可以证明,随机一次成功的概率大于等于 \(\frac{3}{4}\)

考虑我们要满足的性质:

  1. \(a \ne b \ne c\)
  2. \(a^i + b^i + c^i \ne 0, \forall i \in \{1, n, 2n, 3n\}\)

前者概率为 \(O(\frac{1}{p})\),考虑后者。

我们可以证明,\(a^i + b^i + c^i = 0\) 的概率小于等于 \(\frac{1}{4}\)

我们设 \(S\) 集合为所有的非零的 \(a^i\) 的取值,那么分几种情况:

\(m\)\(S\) 集合的大小,可以发现,如果 \(x \in S\),那么 \(x^k \in S\),那么实际上 \(S\) 就是某个单位根集合,即有 \(x^m \equiv 1\)

  1. \(m = 1 / 2\):那么说明 \(S = \{1\} / \{\pm 1\}\),由于 \(p \ge 5\),可以发现不可能等于 \(0\)
  2. \(m = 3\):说明有三个数 \((x, y, z)\),且 \(x + y + z = 0\),由于 \(x^3 \equiv 1\),且 \(p \ge 5\),那么有 \((-2x)^3 \ne 1\),即 \(-2x \ne 1\),则 \(x^3 - (-2y)^3 \ne 0\),即 \(x + 2y \ne 0\),这意味着如果有两个相同的数,和一定不等于 \(0\)。那么随机选取三个数,两两不相同的概率就是 \(\frac{3!}{3^3} = \frac{6}{27} < \frac{1}{4}\)
  3. \(m \ge 4\):那么固定 \((a, b)\),假如 \(-a^i-b^i \not \in S\),那么不可能等于 \(0\);否则,选中这个数的概率为 \(\frac{1}{m} \le \frac{1}{4}\)

综上可知等于 \(0\) 的概率为 \(\frac{1}{4}\)

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005, P = 998244353;
int T;
int n, p;
mt19937 rd(chrono::system_clock::now().time_since_epoch().count());
int Rand(int l, int r) {
    return uniform_int_distribution<int>(l, r)(rd);
}
long long qpow(int a, long long b) {
    int ans = 1;
    while (b) {
        if (b & 1) ans = 1ll * ans * a % p;
        a = 1ll * a * a % p;
        b >>= 1;
    }
    return ans;
}
int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d", &n, &p);
        while (true) {
            long long a = Rand(1, p - 1), b = Rand(1, p - 1), c = Rand(1, p - 1);
            if (a == b || a == c || b == c) continue;
            int x = (a + b + c) * (qpow(a, n) + qpow(b, n) + qpow(c, n)) % p * (qpow(a, 2ll * n) + qpow(b, 2ll * n) + qpow(c, 2ll * n)) % p;
            int y = (qpow(a, 3ll * n) + qpow(b, 3ll * n) + qpow(c, 3ll * n)) % p;
            if (x != 0 && y != 0) {
                int t = 1ll * y * qpow(x, p - 2) % p;
                vector<long long> ans = { 1ll * a * t % p, 1ll * b * t % p, 1ll * c * t % p };
                sort(ans.begin(), ans.end());
                printf("%lld %lld %lld\n", ans[0], ans[1], ans[2]);
                break;
            }
        }
    }
    return 0;
}
posted @ 2023-03-13 10:20  APJifengc  阅读(62)  评论(0编辑  收藏  举报