# bzoj 2440

question

slove

=0个质数乘积的平方的倍数的数的数量(1的倍数)
-每个质数的平方的倍数的数的数量(9的倍数,25的倍数, $\dots$ )
+每2个质数乘积的平方的倍数的数的数量(36的倍数,100的倍数, $\dots$ )
-$\dots$

then，check时只需判断 $Q(x) = \sum_{i=1}^{\lfloor \sqrt(x) \rfloor} \mu(i) \lfloor \frac{x}{i^2} \rfloor$ 与 $mid$ 的大小即可

#include <bits/stdc++.h>

#define LL long long

const int N = 1e5 + 10;

LL T, n, miu[N], prime[N], bo[N];

void Make_miu() {
miu[1] = 1;
for(int i = 2; i < N; i ++) {
if(!bo[i]) {prime[++ prime[0]] = i; miu[i] = -1;}
for(int j = 1; j <= prime[0] && prime[j] * i < N; j ++) {
bo[i * prime[j]] = 1;
if(i % prime[j] == 0) {
miu[i * prime[j]] = 0;
break;
} else {
miu[i * prime[j]] = - miu[i];
}
}
}
}

bool See(LL x, LL t) {
LL ret(0);
for(LL i = 1; i * i <= x; i ++) ret += (miu[i] * (x / (i * i)));
return ret < t;
}

LL Get_Ans(LL x) {
LL L = 0, R = x * 2, Ans;
while(L <= R) {
LL Mid = (L + R) >> 1;
if(See(Mid, x)) L = Mid + 1, Ans = Mid;
else R = Mid - 1;
}
return Ans;
}

int main() {
std:: cin >> T;
Make_miu();
for(; T --; ) {
std:: cin >> n;
std:: cout << Get_Ans(n) + 1 << "\n";
}
return 0;
} 

posted @ 2018-06-25 19:42  qmey  阅读(77)  评论(0编辑  收藏  举报