HDU5778 abs

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\n",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\n",ans);
151     }
152     return 0;
153 }

 

转载于:https://www.cnblogs.com/ITUPC/p/5722885.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值