HYSBZ 2440 完全平方数(莫比乌斯反演)

时间:2024-09-26 19:03:50

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2440

若i为质数,n为i*i的倍数,则称n为含平方因子数。

求1~n的无平方因子数。

F(x)为1~x的平方因子数数量,则由容斥原理及莫比乌斯函数知:

HYSBZ 2440 完全平方数(莫比乌斯反演)

G(x)为1~x的无平方因子数数量,则:

HYSBZ 2440 完全平方数(莫比乌斯反演)

二分法枚举,注意二分法的写法。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<vector>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=;
bool vis[N];
int mu[N];
int prime[N];
void Mobius(int n){
memset(vis,,sizeof(vis));
mu[]=;
int tot=;
for(int i=;i<=n;i++){
if(!vis[i]){
prime[tot++]=i;
mu[i]=-;
}
for(int j=;j<tot&&i*prime[j]<=n;j++){
vis[i*prime[j]]=true;
if(i%prime[j]==){
mu[i*prime[j]]=;
break;
}else{
mu[i*prime[j]]=-mu[i];
}
}
}
} LL getNum(int n){
int e = (int)sqrt(n);
LL ans = ;
for(LL i = ; i <= e; i++){
ans += mu[i] * (LL)(n/(i * i));
}
return ans;
}
int main(){
Mobius(N - );
int t, k;
scanf("%d", &t);
while(t--){
scanf("%d", &k);
LL l = , r = * k + ;
while(l < r){
LL mid = (l + r)/;
if(getNum(mid) < k){
l = mid + ;
}else{
r = mid;
}
}
printf("%lld\n", l);
}
return ;
}