1. 程式人生 > >BZOJ2440: [中山市選2011]完全平方數

BZOJ2440: [中山市選2011]完全平方數

problem pil make tdi lin push_back init esp Language

容斥原理,發現正好可以用上莫比烏斯函數

 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

BZOJ2440: [中山市選2011]完全平方數