求第$k$个没有完全平方数因数的数
一开始是想筛一波莫比乌斯函数,然后发现时间复杂度要炸
于是老老实实看了题解
一个数的排名$k=x-\sum_{i=1}^{x}{(1-|\mu(i)|)}$
因为$k$是不降的,所以我们可以考虑二分
那么如何计算区间$[1,x]$的无完全平方数因数的数的个数嘞?
我们可以考虑计算有平方因数的数的个数再减掉就可以了
那么这个可以用一个容斥计算,就是0个完全平方数因数的个数(即1的倍数)-1个完全平方数因数个数(即4,9,16...的倍数)+2个...
然后不难发现这个容斥里每一项的系数是$\mu(i)$(别问我我也不知道)
然后带进去瞎搞就好了
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline int read(){ 9 #define num ch-'0' 10 char ch;bool flag=0;int res; 11 while(!isdigit(ch=getc())) 12 (ch=='-')&&(flag=true); 13 for(res=num;isdigit(ch=getc());res=res*10+num); 14 (flag)&&(res=-res); 15 #undef num 16 return res; 17 } 18 const int N=5e4+5; 19 int vis[N],p[N],mu[N],m; 20 void init(){ 21 mu[1]=1; 22 for(int i=2;i<=50000;++i){ 23 if(!vis[i]) p[++m]=i,mu[i]=-1; 24 for(int j=1;j<=m&&i*p[j]<=50000;++j){ 25 vis[i*p[j]]=1; 26 if(i%p[j]==0) break; 27 mu[i*p[j]]=-mu[i]; 28 } 29 } 30 } 31 inline int work(int k){ 32 int res=0,lim=sqrt(k); 33 for(int i=1;i<=lim;++i) 34 res+=mu[i]*(k/i/i); 35 return res; 36 } 37 int main(){ 38 // freopen("testdata.in","r",stdin); 39 init(); 40 int T=read(); 41 while(T--){ 42 int k=read(); 43 int l=1,r=2e9,ans; 44 while(l<=r){ 45 int mid=(1ll*l+r)>>1,x=work(mid); 46 if(x>=k) ans=mid,r=mid-1; 47 else l=mid+1; 48 } 49 printf("%d\n",ans); 50 } 51 return 0; 52 }