D - 2-variable Function Editorial by en_translator
Let \(f(a,b)=a^3+a^2b+ab^2+b^3\).
First, since \(N \le 10^{18}\), when the answer is \(f(a,b)\), then \(a,b \le 10^6\). (This is because, being \(f(10^6,0)=10^{18}\), if at least one of \(a\) and \(b\) is greater than \(10^6\), we have \(f(a,b)>10^{18}\).)
Thus, the objective of this problem is to find for all \(0 \le i \le 10^6\) the minimum non-negative integer \(j\) such that \(f(i,j) \ge N\) and find \(\min f(i,j)\) over all of them.
Here, let \(i_1\) and \(i_2\) be non-negative integers, \(j_1\) be the \(j\) corresponding to \(i=i_1\), and \(j_2\) be the \(j\) corresponding to \(i=i_2\); then it holds that \(j_1 \ge j_2\). (When \(f(i_1,j_1) \ge N\), it holds that \(f(i_2,j_1) \ge N\).)
By this property, the following algorithm is valid.
- First, initialize a variable \(j=10^6\). Let \(X= \infty\) be a variable to store the candidate of the solution.
- For each of \(i = 0\) through \(10^6\), repeat the following.
- While \(f(i,j) \ge N\) and \(j \ge 0\), repeat the following.
- Let \(X=\min(X,f(i,j))\), and then decrement \(j\).
- While \(f(i,j) \ge N\) and \(j \ge 0\), repeat the following.
Sample code (C++):
#include<bits/stdc++.h>
using namespace std;
long long f(long long a,long long b){
return (a*a*a + a*a*b + a*b*b + b*b*b);
}
int main(){
long long n;
cin >> n;
long long x=8e18;
long long j=1000000;
for(long long i=0;i<=1000000;i++){
while(f(i,j)>=n && j>=0){
x=min(x,f(i,j));
j--;
}
}
cout << x << '\n';
return 0;
}
Here is another implementation equivalent to this algorithm, which is faster by a constant factor. The implementation is essentially that of sliding window technique.
Sample code (C++):
#include<bits/stdc++.h>
using namespace std;
long long f(long long a,long long b){
return (a*a*a + a*a*b + a*b*b + b*b*b);
}
int main(){
long long n;
cin >> n;
long long x=8e18;
long long i=0,j=1000000;
while(i<=j){
long long cf=f(i,j);
if(cf>=n){x=min(x,cf);j--;}
else{i++;}
}
cout << x << '\n';
return 0;
}
posted:
last update: