BZOJ2440: [中山市选2011]完全平方数

容斥原理,发现正好可以用上莫比乌斯函数

 1 /**************************************************************
 2     Problem: 2440
 3     User: white_hat_hacker
 4     Language: C++
 5     Result: Accepted
 6     Time:6616 ms
 7     Memory:35144 kb
 8 ****************************************************************/
 9  
10 #include<cstdio>
11 #include<cstdlib>
12 #include<algorithm>
13 #include<cstring>
14 #include<vector>
15 #include<cmath>
16 #include<queue>
17 #define MAXN 4000000+10
18 #define INF 0x7f7f7f7f
19 #define LINF 0x7f7f7f7f7f7f7f7f
20 #define ll long long
21 #define pb push_back
22 #define ft first
23 #define sc second
24 #define mp make_pair
25 #define pil pair<int,ll>
26 #define pll pair<ll,ll>
27 using namespace std;
28 int mu[MAXN];
29 vector<int> p;
30 int b[MAXN];
31 void init(){
32     mu[1]=1;
33     for(int i=2;i<MAXN;i++){
34         if(!b[i]){
35             p.pb(i);
36             mu[i]=-1;
37         }
38         for(int j=0;j<p.size()&&i*p[j]<MAXN;j++){
39             b[i*p[j]]=1;
40             if(i%p[j]==0){
41                 mu[i*p[j]]=0;
42                 break;
43             }
44             mu[i*p[j]]=-mu[i];
45         }
46     }
47 } 
48 ll check(ll x){
49     ll ret=0LL;
50     for(ll i=1;i*i<=x;i++){
51         ret+=mu[i]*(x/(i*i));
52     }
53     return ret;
54 }
55 ll k;
56 ll solve(){
57     scanf("%lld",&k);
58     ll L=1LL,R=1644934081;
59     while(R-L>1LL){
60         ll mid=(L+R)>>1;
61         ll c=check(mid);
62         if(c>=k){
63             R=mid;
64         }
65         else{
66             L=mid;
67         }
68     }
69     if(check(L)==k)return L;
70     else return R;  
71 }
72 int main()
73 {
74 //  freopen("data.in","r",stdin);
75     init();
76     int T;
77     scanf("%d",&T);
78     while(T--){
79         printf("%lld\n",solve());
80     }
81     return 0;
82 }
83 

 

posted @ 2018-01-27 23:09  white_hat_hacker  阅读(101)  评论(0编辑  收藏  举报