- 题意: 输入k,输出第K个因子中不含完全平方数的值。k < 1e9
- 题解:
容斥思想:先减4的倍数的个数,再减去9的倍数的个数...由于多减了,还要加上36的倍数的个数...每个值加还是减根据莫比乌斯函数mu[i]判断。
二分:范围很大,就可以想到二分,二分答案求1~x之间有多少无平方因子数。
对0~sqrt(n)以内所有的质数, x以内无平方因子数 = 0个质数乘积的平方的倍数的数的数量 - 每个质数的平方的倍数的数量 + 每2个质数乘积的平方的倍数的数量....
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 4e5 + 5;
int pri[N], cnt;
int mu[N];
int vis[N];
ll T, k;
void prime(){
mu[1] = 1;
for(int i = 2; i <= 4e5; ++ i){
if(!vis[i]){
pri[++ cnt] = i;
mu[i] = -1;
}
for(int j = 1; j <= cnt && pri[j] * i <= 4e5; ++ j){
vis[pri[j] * i] = 1;
if(i % pri[j] == 0){
mu[pri[j] * i] = 0;
break;
}
mu[pri[j] * i] = -mu[i];
}
}
}
bool check(ll x){
ll div = sqrt(x);
ll sum = 0;
for(ll i = 1; i <= div; ++ i){
if(mu[i]) sum += mu[i] * x / (i * i);
}
return sum >= k;
}
int main()
{
prime();
scanf("%lld",&T);
while(T --){
scanf("%lld", &k);
ll l = 1, r = 2 * k + 1;
while(l < r){
ll mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
printf("%lld\n",l);
}
return 0;
}