2017.3.11[bzoj2440][中山市选2011]完全平方数

线性筛+莫比乌斯函数裸题

http://www.lydsy.com/JudgeOnline/problem.php?id=2440

考虑二分答案,对于每个数看它是第几个,即对于这个数看比他小的有多少个素数的平方的倍数,减去,注意重复的要用容斥原理。

然后对于容斥原理就跪了……一开始打的暴力dfs……

事实上只要用莫比乌斯函数就好了。根据定义,莫比乌斯函数就体现了当前数是否是没有平方因子,且有k个不同的质因子的数。直接乘即可。

没开够long longWA了一次……

 1 /**************************************************************
 2     Problem: 2440
 3     User: Super_Nick
 4     Language: C++
 5     Result: Accepted
 6     Time:6656 ms
 7     Memory:89192 kb
 8 ****************************************************************/
 9  
10 #include<cmath>
11 #include<queue>
12 #include<cstdio>
13 #include<vector>
14 #include<cstdlib>
15 #include<cstring>
16 #include<iostream>
17 #include<algorithm>
18 #define RG register
19 #define LYM 10000010
20 #define K 1000000010
21 #define inf 0x3f3f3f3f
22 #define Inf 99999999999999999LL
23 using namespace std;
24 typedef long long LL;
25 bool vis[LYM];
26 LL l,r,ans,mid;
27 int k,lim,top,T,num[LYM],sta[LYM];
28 inline int gi(){
29     RG int x=0;RG bool flag=0;RG char c=getchar();
30     while((c<'0'||c>'9')&&c!='-') c=getchar();
31     if(c=='-') c=getchar(),flag=1;
32     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
33     return flag?-x:x;
34 }
35 inline void init(){
36     num[1]=1;
37     for (RG int i=2;i<LYM;++i){
38     if(!vis[i]){
39         num[i]=-1;
40         sta[++top]=i;
41     }
42     for (RG int j=1;j<=top&&i*sta[j]<LYM;++j){
43         vis[i*sta[j]]=1;
44         if(i%sta[j]==0){
45         num[i*sta[j]]=0;
46         break;
47         }
48         else
49         num[i*sta[j]]=-num[i];
50     }
51     }
52 }
53 inline bool check(){
54     RG LL sum=0;
55     lim=sqrt(mid);
56     for (RG int i=1;i<=lim;++i)
57     sum+=(LL)num[i]*((LL)mid/((LL)i*(LL)i));
58     if(sum>=k) return 1;
59     return 0;
60 }
61 inline void work(){
62     k=gi();
63     if(k==1){
64     printf("1\n");
65     return;
66     }
67     l=k,r=1644934081;
68     while(l<=r){
69     mid=(l+r)>>1;
70     if(check()) ans=mid,r=mid-1;
71     else        l=mid+1;
72     }
73     printf("%lld\n",ans);
74 }
75 int main(){
76     init();T=gi();
77     while(T--) work();
78     return 0;
79 }
View Code

 

posted @ 2017-03-11 19:04  Super_Nick  阅读(163)  评论(0编辑  收藏  举报