根据y的性质,容易想到 令y=z*z;则题目转化为求z(2<=z<1e9)。所以从sqrt(x)从左右开始枚举z,判断z是否符合要求。
显然,如果z是素数,一定是符合要求的。所以必定会在log1e9时间内找到一个符合要求的z。
在判断z是否符合要求(没有相同的质因子)时,可以先预处理出1e9所有可能的质因子(即sqrt(1e9)内的质数),然后如果z对于某个质因子可以连续整除2次,说明z不符合要求。
【代码】
/* ***********************************************
Author :angon
************************************************ */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define REP(i,k,n) for(int i=k;i<n;i++)
#define REPP(i,k,n) for(int i=k;i<=n;i++)
#define scan(d) scanf("%d",&d)
#define scann(n,m) scanf("%d%d",&n,&m)
#define mst(a,k) memset(a,k,sizeof(a));
#define LL long long
#define maxn 1005
#define mod 100000007
const int N = 100000;
int prime[N] = {0},num_prime = 0;
int isNotPrime[N] = {1, 1};
void get_prime()
{
for(long i = 2 ; i < N ; i ++)
{
if(! isNotPrime[i])
prime[num_prime ++]=i;
for(long j = 0 ; j < num_prime && i * prime[j] < N ; j ++)
{
isNotPrime[i * prime[j]] = 1;
if( !(i % prime[j] ) )
break;
}
}
}
bool judge(int y)
{
for(int i=0;i<num_prime && prime[i]*prime[i]<=y;i++)
{
if(y%prime[i]==0)
{
y/=prime[i];
if(y%prime[i]==0)
return false;
}
}
return true;
}
int main()
{
get_prime();
int t; scan(t);
while(t--)
{
LL x; scanf("%lld",&x);
LL y=sqrt(x);
LL l=y, r=y+1;
while(l&&judge(l)==0) --l;
while(judge(r)==0) ++r;
LL ans = r*r-x;
if(l>1) ans = min(ans,x-l*l);
printf("%I64d\n",ans);
}
return 0;
}