注意的两点是二分的时候注意,要选取最小的那个答案,因为19是13个,20也是13个,而很明显19才是符合答案的。
还有感觉题目给的数据范围不对,实际比较大,所以二分的时候r大点。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int prime[maxn];
bool check[maxn];
int mu[maxn];
void moblus(){
memset(check,false,sizeof check);
mu[1]=1;
int tot=0;
for(int i=2;i<maxn;i++){
if(!check[i]){
prime[tot++]=i;
mu[i]=-1;
}
for(int j=0;j<tot;j++){
if(i*prime[j]>=maxn) break;
check[i*prime[j]]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}else{
mu[i*prime[j]]=-mu[i];
}
}
}
}
typedef long long ll;
ll solve(ll mid){
ll ans=0;
for(ll i=1;i*i<=mid;i++){
ans+=mu[i]*(mid/(i*i));
}
return ans;
}
int main(){
moblus();
int T;
scanf("%d",&T);
while(T--){
ll n;
scanf("%lld",&n);
ll l=1;
ll r=2e10;
ll ans;
while(l<=r){
ll mid=(l+r)>>1;
if(solve(mid)<n){
l=mid+1;
}else{
ans=mid;
r=mid-1;
}
}
printf("%lld\n",ans);
}
}