http://acm.hdu.edu.cn/showproblem.php?pid=5778
思路:只有平方质因子的数,也就是这题所说的 y的质因数分解式中每个质因数均恰好出现2次 满足条件的数很幂集
因此枚举sqrt(x),前后判断一下sqrt(x)的质因子就可以
可以不判断是不是素数
注意x<4的情况
1 // #pragma comment(linker, "/STACK:102c000000,102c000000") 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <sstream> 6 #include <string> 7 #include <algorithm> 8 #include <list> 9 #include <map> 10 #include <vector> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <cstdlib> 15 // #include <conio.h> 16 using namespace std; 17 #define pi acos(-1.0) 18 const int N = 100000 + 50; 19 #define inf 0x7fffffff 20 typedef long long LL; 21 22 void fre() { freopen("in.txt","r",stdin);} 23 24 bool isPrime[N]; 25 LL primeList[N],primeCount = 0; 26 27 LL Fast_power(LL n,LL k,LL mod) { 28 if(k == 0) return 1; 29 LL temp = Fast_power(n,k / 2,mod); 30 temp = (temp * temp) % mod; 31 if(k % 2 == 1) temp = (temp * (n % mod)) % mod; 32 return temp; 33 } 34 35 void Eular_Sieve(LL n) { 36 memset(isPrime,true,sizeof(isPrime)); 37 isPrime[0] = false; 38 isPrime[1] = false; 39 for(int i = 2; i <= n; i ++) { 40 if(isPrime[i]) { 41 primeCount ++; 42 primeList[primeCount] = i; 43 } 44 for(int j = 1; j <= primeCount; j ++) { 45 if(i * primeList[j] > n) break; 46 isPrime[i * primeList[j]] = false; 47 if(!(i % primeList[j])) break; 48 } 49 } 50 } 51 52 int Mr[30] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; 53 bool Miller_Rabin(LL n) { 54 if(n == 2) return true; 55 else if(n < 2) return false; 56 if(n % 2 == 0) return false; 57 LL u = n - 1; 58 while(u % 2 == 0) u = u / 2; 59 int tempu = u; 60 for(int i = 0; i < 12; i ++) { 61 if(Mr[i] >= n) break; 62 u = tempu; 63 LL x = Fast_power(Mr[i],u,n); 64 while(u < n) { 65 LL y = (x % n) * (x % n) % n; 66 if(y == 1 && x != 1 && x != n - 1) return false; 67 x = y; 68 u = u * 2; 69 } 70 if(x != 1) return false; 71 } 72 return true; 73 } 74 75 int main() { 76 // fre(); 77 Eular_Sieve(100010); 78 int T; 79 scanf("%d",&T); 80 while(T --) { 81 LL n; 82 scanf("%I64d",&n); 83 if(n<=4){ 84 printf("%d ",4-n); 85 continue; 86 } 87 LL x = sqrt(n); 88 LL y = sqrt(n) + 1; 89 LL cnt = 0,ans = 0; 90 while(1) { 91 LL xx = x - cnt; 92 if(Miller_Rabin(xx)) { 93 ans = n - xx * xx; 94 break; 95 } else { 96 LL pp = xx; 97 bool flag = true; 98 for(int i = 1; i < primeCount && i * i <= pp; i ++) { 99 int cou = 0; 100 while(pp % primeList[i] == 0) { 101 pp = pp / primeList[i]; 102 cou ++; 103 if(cou>=2){ 104 break; 105 } 106 } 107 if(cou >= 2) { 108 flag = false; 109 break; 110 } 111 } 112 if(flag == true) { 113 ans = n - xx * xx; 114 break; 115 } 116 } 117 cnt ++; 118 } 119 cnt = 0; 120 while(1) { 121 LL yy = y + cnt; 122 if(yy * yy - n >= ans) break; 123 if(Miller_Rabin(yy)) { 124 ans = min(ans,yy * yy - n); 125 break; 126 } else { 127 LL pp = yy; 128 bool flag = true; 129 for(int i = 1; i < primeCount && i * i <= pp; i ++) { 130 int cou = 0; 131 while(pp % primeList[i] == 0) { 132 pp = pp / primeList[i]; 133 cou ++; 134 if(cou>=2){ 135 break; 136 } 137 } 138 if(cou >= 2) { 139 flag = false; 140 break; 141 } 142 } 143 if(flag == true) { 144 ans = min(ans,yy * yy - n); 145 break; 146 } 147 } 148 cnt ++; 149 } 150 printf("%I64d ",ans); 151 } 152 return 0; 153 }