# [BZOJ 2440] [中山市选2011] 完全平方数 【二分 + 莫比乌斯函数】

### 题目分析

mou(x) = {

1 (x = 1)

(-1)^k  (x = p1 * p2 * ... * pk)

0 (x % pi^2 = 0)

}

### 代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

typedef long long LL;

const int MaxN = 100000 + 5;

int T, n, k, Top;
int Mou[MaxN], Prime[MaxN];

bool isPrime[MaxN];

void Prepare()
{
n = 100000;
for (int i = 1; i <= n; ++i) isPrime[i] = true;
isPrime[1] = false; Mou[1] = 1;
Top = 0;
for (int i = 2; i <= n; ++i)
{
if (isPrime[i])
{
Prime[++Top] = i;
Mou[i] = -1;
}
for (int j = 1; j <= Top && i * Prime[j] <= n; ++j)
{
isPrime[i * Prime[j]] = false;
if (i % Prime[j] == 0)
{
Mou[i * Prime[j]] = 0;
break;
}
Mou[i * Prime[j]] = -Mou[i];
}
}
}

int Calc(int x)
{
int ret = 0, SqrtX;
SqrtX = (int)sqrt((double)x);
for (int i = 1; i <= SqrtX; ++i)
ret += Mou[i] * x / i / i;
return ret;
}

int main()
{
scanf("%d", &T);
Prepare();
for (int Case = 1; Case <= T; ++Case)
{
scanf("%d", &k);
LL l = 1, r = k << 1, mid, Ans;
while (l <= r)
{
mid = (l + r) >> 1;
if (Calc((int)mid) >= k)
{
Ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
printf("%d\n", (int)Ans);
}
return 0;
}


posted @ 2015-04-03 20:48  JoeFan  阅读(241)  评论(0编辑  收藏  举报