题意:给定一个数x,求正整数y≥2y\geq 2y2,使得满足以下条件: 1.y-x的绝对值最小 2.y的质因数分解式中每个质因数均恰好出现2次。

析:由于y质因数分解式中每个质因数均出现2次,那么y是一个完全平方数,设y=z*z,题目可转换成求z,使得每个质因数出现1次. 我们可以暴力枚举z,检查z是否符合要求,

显然当z是质数是符合要求,由素数定理可以得,z的枚举量在logn级别 复杂度 O(n4logn2\sqrt[4]{n}log\sqrt[2]{n}。

注意y>=2。

代码如下:

#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
using namespace std ;
typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1e5 + 5;
const int dr[] = {0, 0, -1, 1};
const int dc[] = {-1, 1, 0, 0};
int n, m;
inline bool is_in(int r, int c){
    return r >= 0 && r < n && c >= 0 && c < m;
}
inline bool solve(LL x){
    int n = (int)sqrt(x+0.5);
    for(int i = 2; i <= n; ++i) if(x % i == 0){
        x /= i;
        if(x % i == 0)  return true;
    }
    return false;
}

int main(){
   // ios::sync_with_stdio(false);
    int T, q;  cin >> T;
    while(T--){
        LL x;
        cin >> x;
        LL t1 = (LL)sqrt(x*1.0);
        LL t2 = t1+1;
        while(t1 > 1 && solve(t1))  --t1;
        while(solve(t2))  ++t2;
        LL ans = abs(t2*t2-x);
        if(t1 >= 2)  ans = min(ans, abs(t1*t1-x));
        cout << ans << endl;
    }
    return 0;
}

 

4​​n​​log2​​n​​)