$$$a^{3}+b^{3}$$$ 是一个对称式(即交换 $$$a,b$$$ 原式值不变)。所以可以认为 $$$a<=b$$$,因为 $$$a>b$$$ 的情况相当于把 $$$a$$$ 与 $$$b$$$ 交换。
所以可以直接枚举 $$$a$$$,然后算出 $$$b=^{3}\kern{-8pt}\sqrt{n-a^{3}}$$$。如果 $$$b$$$ 是正整数,则输出yes
并结束程序。否则继续枚举。若枚举完所有 $$$a$$$ 仍未找到,则输出no
。
现在的重点是如何求 $$$^{3}\kern{-8pt}\sqrt{n-a^{3}}$$$,设结果为 $$$ans$$$,由于 $$$ans^{2}$$$ 满足单调性,所以二分 $$$ans$$$ 即可。
小技巧:由于 $$$^{3}\kern{-8pt}\sqrt{n-a^{3}}$$$ 可能不为整数,这时如果把小数的值也枚举出来很费时间,所以只需要枚举其整数值,然后判断 $$$ans^{3}$$$ 是否等于 $$$n-a$$$ 即可。若等于则说明是整数,输出yes
,否则继续枚举。
细节:注意二分的上界最多为 $$$10^{4}$$$ 。不然算立方时会爆longlong。
单组数据时间复杂度: $$$O(^{3}\kern{-8pt}\sqrt{x} \times log_{2}(x))$$$ 。
#include<iostream>
using namespace std;
long long sqrt3(long long a){
long long l=1,r=min(10000ll,a),m;
while(l<=r){
m=l+r>>1ll;
if(m*m*m<a){
l=m+1ll;
}else{
r=m-1ll;
}
}
return l;
}
void Main(){
long long n,i,a,b=9223372036854775807ll; //b一定要初始化,否则一开始就进不去a<=b的循环。
cin>>n;
for(a=1;a<=b;a++){
b=sqrt3(n-a*a*a);
if(a*a*a+b*b*b==n){
cout<<"yes"<<endl;
return;
}
}
cout<<"no"<<endl;
}
int main(){
long long t,i;
cin>>t;
for(i=0;i<t;i++){
Main();
}
return 0;
}