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 }

 

posted @ 2016-03-30 17:03  HugeGun  阅读(159)  评论(0编辑  收藏  举报