1. 程式人生 > >BZOJ 2440 中山市選2011 完全平方數

BZOJ 2440 中山市選2011 完全平方數

這道題目就是問你第k個不是完全平方數正整數倍的數。
好像挺顯然的,直接亂搞就好。我們考慮下二分,將問題轉化為求函式

f(n)=x=1ni=1[x][i2x]然後利用莫比烏斯反演,我們對於F(i)=x=1n[i2|x]=[ni]利用反演f(i)=i|dμ(di)F(d)每次暴力列舉因子計算就好了,不過這題需要注意的是容斥的時候要反過來……
時間複雜度O(Tklogk)。程式碼:
# include <cstdio>
using namespace std;
typedef long long ll;
const ll INF = 1644934081;
const int
maxn = 50010; const int maxs = 50000; int pri[maxn],tot=0; bool mark[maxn]; int mu[maxn]={0,-1}; void getmu() { mu[1]=1; for(int i=2;i<=maxs;i++) { if(!mark[i])pri[++tot]=i,mu[i]=-1; for(int j=1;j<=tot&&pri[j]*i<=maxs;j++) { mark[i*pri[j]]=1; if
(i%pri[j]==0){mu[i*pri[j]]=0;break;} else mu[i*pri[j]]=-mu[i]; } } } ll get_sum(ll x){ ll ans = 0; for (ll i=1;i*i<=x;++i){ ans = ans + x/(i*i)*mu[i]; // printf("%lld ",x/(i*i)*mu[i]); } // printf("%lld ",ans); return ans; } ll x; ll l,r,mid; ll ans; int
main(){ getmu(); int T; scanf("%d",&T); while (T--){ scanf("%lld",&x); // printf("%lld\n",x); l = x; r = INF; while (l <= r){ // printf("%lld %lld\n",l,r); mid = (l+r)>>1; if (get_sum(mid) >= x){ ans=mid; r=mid-1; } else l=mid+1; } printf("%lld\n",ans); } return 0; }