bzoj2440 [中山市选2011]完全平方数
首先二分答案,将问题转化为求$n$以内的 含有平方因子数 的个数
由于合数的平方一定是某个质数的平方的倍数,因此我们只考虑质数
由于是平方,所以只考虑$\sqrt{n}$内的质数的平方
含有平方因子数 的个数就用容斥原理计算,直接dfs会T,所以可以预处理出$10^6$以内的$\mu(i)$
即可在$O(\sqrt{n}\ log_2{n})$回答每一个询问
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<string> 5 #include<cstring> 6 #include<cmath> 7 #define re(i,l,r) for(int i=(l);i<=(r);i++) 8 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 9 using namespace std; 10 typedef long long LL; 11 int prime[100010],mu[100010],prime_tot; 12 bool bo[100010]; 13 int T; 14 LL js(LL mid) 15 { 16 int ret=0; 17 LL nn=sqrt(mid+1); 18 re(i,1,nn)ret+=mu[i]*(mid/(1LL*i*i)); 19 return ret; 20 } 21 LL check(LL mid) 22 { 23 return mid-js(mid); 24 } 25 int main() 26 { 27 re(i,2,100000) 28 { 29 if(!bo[i])prime[++prime_tot]=i,mu[i]=1; 30 for(int j=1;j<=prime_tot&&i*prime[j]<=100000;j++) 31 { 32 bo[i*prime[j]]=1; 33 if(i%prime[j]==0){mu[i*prime[j]]=0;break;} 34 else mu[i*prime[j]]=-mu[i]; 35 } 36 } 37 scanf("%d",&T); 38 while(T--) 39 { 40 int n;scanf("%d",&n); 41 LL l=n,r=l<<1,mid,ans; 42 while(l<=r) 43 { 44 mid=(l+r)>>1; 45 LL temp=check(mid); 46 if(temp>=n)ans=mid,r=mid-1; 47 else l=mid+1; 48 } 49 printf("%lld\n",ans); 50 // printf("%lld\n",js(n)); 51 } 52 return 0; 53 }