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;
}
投稿日時:
最終更新: