链接:戳这里
思路:首先我们要把完全平方数和完全平方数的倍数叉掉, 4 9 25 12 16 18 25 50 这些类似的
莫比乌斯反演的筛选函数里面有一个mu[i]函数,是一个积性函数 mu[3]=-1 mu[6]=1
可以自行百度,然后这里可以很巧妙的应用这个mu[i]函数, 显然我们筛4 9 的倍数的时候36会筛掉两次,但是mu[6]=1,我们又可以用这个加回来 具体看代码吧
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int n,cnt; int mu[1000100],prime[1000100],vis[1000100]; void Moblus(){ mu[1]=1; cnt=0; mst(vis,0); for(int i=2;i<=1000000;i++){ if(!vis[i]){ prime[++cnt]=i; mu[i]=-1; } for(int j=1;j<=cnt;j++){ if(i*prime[j]>1000000) break; vis[i*prime[j]]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } } } ll solve(ll n){ ll ans=0; for(ll i=1;i*i<=n;i++){ ans+=(n/(i*i))*mu[i]; } return ans; } int main(){ Moblus(); /// for(int i=1;i<=60;i++) cout<<i<<"="<<mu[i]<<endl; int T,k; scanf("%d",&T); while(T--){ scanf("%d",&k); ll l=k,r=1e10,mid,ans; while(l<r){ mid=(l+r)/2; if(solve(mid)<k) l=mid+1; else r=mid,ans=mid; } cout<<ans<<endl; } return 0; }