# 【整体二分+莫比乌斯函数+容斥原理】BZOJ2440

【题目大意】

【思路】

由于μ(i)*(n/i^2)=n，可以直接从1开始，得出非完全平方数/完全平方数倍数的数的个数

int lb=下界-1,ub=上界

while (ub-lb>1)

{

int mid=(lb+ub)>>1;

if (a[mid]>=k) ub=mid; else lb=mid;

}

ans=ub;

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 typedef long long ll;
7 const ll MAXN=50000+50;
8 const ll INF=0x7fffffff;
9 int T;
10 ll k;
11 int miu[MAXN];
12 ll prime[MAXN];
13 int pnum=0;
14
15 void get_miu()
16 {
17     for (int i=0;i<MAXN;i++) miu[i]=-INF;
18     miu[1]=1;
19     for (int i=2;i<MAXN;i++)
20     {
21         if (miu[i]==-INF)
22         {
23             miu[i]=-1;
24             prime[++pnum]=i;
25         }
26         for (int j=1;j<=pnum;j++)
27         {
28             if (i*prime[j]>=MAXN) break;
29             if (i%prime[j]==0) miu[i*prime[j]]=0;
30                 else miu[i*prime[j]]=-miu[i];
31         }
32     }
33 }
34
35 ll square(ll x)
36 {
37     ll res=0;
38     for (int i=1;i*i<=x;i++) res+=miu[i]*(x/(i*i));
39     return res;
40 }
41
42 ll get_ans()
43 {
44     ll lb=-1,ub=MAXN*MAXN;
45     while (ub-lb>1)
46     {
47         ll mid=(lb+ub)>>1;
48         ll nowk=square(mid);
49         if (nowk>=k) ub=mid;
50             else lb=mid;
51     }
52     return ub;
53 }
54
55 int main()
56 {
57     get_miu();
58     scanf("%d",&T);
59     for (int i=0;i<T;i++)
60     {
61         scanf("%lld",&k);
62         printf("%lld\n",get_ans());
63     }
64     return 0;
65 }

posted @ 2016-07-01 14:21  iiyiyi  阅读(189)  评论(0编辑  收藏  举报