cpp.sb2's blog

By cpp.sb2, history, 3 years ago, In English

$$$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;
}

Full text and comments »

  • Vote: I like it
  • -140
  • Vote: I do not like it