公式

G - Cubes 解説 by en_translator


\(\mathrm{O}(\sqrt{N})\) solution

By the constraints, \(N >0\). Thus, for \((x,y)\) with \(x^3-y^3=N\), we have \(y+1 \leq x\), and \((y+1)^3-y^3=3y^2 +3y+1 \leq x^3-y^3 =N\). Thus, we have \(y \leq \sqrt{N}\).

Therefore, one bruteforce all integers \(k\) between \(1\) and \(\sqrt{N}\), inclusive, to check if \(k^3+N\) is a cube number; if it is, then \((x,y)=(\sqrt[3]{k^3+N},k)\) is one of the solutions.

Conversely, if there is no such \(k\), then the solution does not exist.

Therefore, the problem can be solved in \(\mathrm{O}(\sqrt{N})\) time. However, it is difficult to be accepted under the constraints of this problem.

\(\mathrm{O}({\sqrt[3]{N}})\) solution

Let \(x-y=d\). For \((x,y)\) with \(x^3-y^3=N\), we have \(x^3-y^3=(x-y) (x^2+xy+y^2)=d(x^2+xy+y^2)\). Also, since \(x^2+xy+y^2 \geq x^2-2xy+y^2 =d^2\), we have \(d^3 \leq d(x^2+xy+y^2) = x^3-y^3 =N\).

Therefore, we have \(d \leq \sqrt[3]{N}\).

Thus, one can bruteforce all integers \(d\) between \(1\) and \(\sqrt[3]{N}\), inclusive, to check if there exists an integer \(k\) with \((k+d)^3-k^3=d^3+3d^2 k+3dk^2=N\). If it exists, then \((x,y)=(k+d,k)\) is one of the solutions.

Conversely, if there is no such \(d\), then the solution does not exist.

Given \(d\), one can find \(k\) satisfying \(d^3+3d^2 k+3dk^2=N\) by deforming it as \(3dk^2+2d^2k+d^3-N=0\) and solving it as a quadratic equation. In our case, we can solve it using the quadratic formula or binary search.

Therefore, the problem can be solved in a total of \(\mathrm{O}(\sqrt[3]{N})\) or \(\mathrm{O}(\sqrt[3]{N}\log N)\) time.

On implementation, beware of overflows. Especially, when finding the solution to the quadratic equation, naively applying the quadratic formula may cause an overflow; using binary search can circumvent the overflow.

Sample code \((\mathrm{O}(\sqrt[3]{N}\log N))\)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll sol(ll a, ll b, ll c) {
    // ax^2 + bx + c = 0の解
    ll l = 0, r = 600000001;
    while (r - l > 1) {
        ll mid = (l + r) / 2;
        if (a * mid * mid + b * mid + c <= 0)
            l = mid;
        else
            r = mid;
    }
    if (a * l * l + b * l + c == 0)
        return l;
    return -1;
}
int main() {
    ll n;
    cin >> n;
    for (ll d = 1; d * d * d <= n; ++d) {
        // (k+d)^3 - k^3 = d^3 + 3*d^2k + 3*d*k^2 = n
        if (n % d != 0)
            continue;
        ll m = n / d; // =3*k^2 + 3*dk + d^2
        ll k = sol(3, 3 * d, d * d - m);
        if (k > 0) {
            cout << k + d << " " << k << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}

投稿日時:
最終更新: