Description
小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
这丝毫不影响他对其他数的热爱。
这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
小X。小X很开心地收下了。
然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?
Input
包含多组测试数据。文件第一行有一个整数 T,表示测试
数据的组数。
第2 至第T+1 行每行有一个整数Ki,描述一组数据,含义如题目中所描述。
Output
含T 行,分别对每组数据作出回答。第 i 行输出相应的
第Ki 个不是完全平方数的正整数倍的数。
二分答案,利用容斥原理计算小于x的完全平方数个数t
t=x-x/2^2-x/3^2-x/5^2+x/(2*3)^2-x/7^2+x/(2*5)^2-x/11^2-x/13^2...
=x-sigma(floor(x/mu(i)*i^2)),i=2,3,4,5...
线性筛处理莫比乌斯函数在0~45000的值即可
#include<cstdio> int ps[45005],mu[45005],isnp[45005]={1,1},p=0; int calc(int x){ int t=x; for(int i=2,j;(j=i*i)<=x;i++)t-=mu[i]*x/j; return t; } bool nt(int x){ for(int i=2;i*i<=x;i++)if(x%(i*i)==0)return 0; return 1; } int main(){ for(int i=2;i<45000;i++){ if(!isnp[i])ps[p++]=i,mu[i]=1; for(int j=0;j<p&&i*ps[j]<45000;j++){ isnp[i*ps[j]]=1; if(i%ps[j]==0){ mu[i*ps[j]]=0; break; }else{ mu[i*ps[j]]=-mu[i]; } } } int T; scanf("%d",&T); while(T--){ unsigned int x,l=1,r,m; scanf("%d",&x); r=x*2+5; while(l+1<r){ m=l+r>>1; if(calc(m)>x)r=m-1; else l=m; } if(calc(l)<x)++l; while(calc(l-1)==x)--l; while(!nt(l)&&calc(l+1)==x)++l; printf("%d\n",l); } return 0; }