# BZOJ 2440 完全平方数（莫比乌斯反演+二分查找）

code：

 1 #include <cstdio>
2 #include <cstring>
3 using namespace std;
4
5 typedef long long LL;
6
7 const LL INF = 2e10 + 7;
8 const int MAXN = 100005;
9
10 bool check[MAXN];
11 int primes[MAXN];
12 int mu[MAXN];
13 LL k;
14
15 void moblus()
16 {
17     memset(check, false, sizeof(check));
18     mu[1] = 1;
19     int cnt = 0;
20     for (int i = 2; i < MAXN; ++i) {
21         if (!check[i]) {
22             primes[cnt++] = i;
23             mu[i] = -1;
24         }
25         for (int j = 0; j < cnt; ++j) {
26             if (i * primes[j] > MAXN) break;
27             check[i * primes[j]] = true;
28             if (i % primes[j] == 0) {
29                 mu[i * primes[j]] = 0;
30                 break;
31             } else {
32                 mu[i * primes[j]] = -mu[i];
33             }
34         }
35     }
36 }
37
38 LL cal(LL n)
39 {
40     LL ret = n;
41     for (LL i = 2; i * i <= n; ++i) {
42         ret += mu[i] * (n / (i * i));
43     }
44     return ret;
45 }
46
47 int main()
48 {
49     moblus();
50     int nCase;
51     scanf("%d", &nCase);
52     while (nCase--) {
53         scanf("%lld", &k);
54         LL lhs = 1L;
55         LL rhs = INF;
56         LL mid;
57         while (lhs < rhs) {
58             mid = (rhs + lhs) / 2;
59             LL tmp = cal(mid);
60             if (tmp < k) lhs = mid + 1;
61             else rhs = mid;
62         }
63         printf("%lld\n", lhs);
64     }
65     return 0;
66 }

posted @ 2015-09-09 11:17  jasaiq  阅读(442)  评论(0编辑  收藏  举报