題目描述
小 X 自幼就很喜歡數。但奇怪的是,他十分討厭徹底平方數。他以爲這些數看起來很使人難受。由此,他也討厭全部是徹底平方數的正整數倍的數。然而這絲絕不影響他對其餘數的熱愛。c++
這天是小X的生日,小 W 想送一個數給他做爲生日禮物。固然他不能送一個小X討厭的數。他列出了全部小X不討厭的數,而後選取了第 K個數送給了小X。小X很開心地收下了。測試
然而如今小 W 卻記不起送給小X的是哪一個數了。你能幫他一下嗎?spa
輸入輸出格式
輸入格式:包含多組測試數據。文件第一行有一個整數 T,表示測試數據的組數。 第2 至第T+1 行每行有一個整數Ki,描述一組數據,含義如題目中所描述。code
輸出格式:含T 行,分別對每組數據做出回答。第 i 行輸出相應的第Ki 個不是徹底平方數的正整數倍的數。blog
輸入輸出樣例
輸入樣例#1:
4 1 13 100 1234567
輸出樣例#1:
1 19 163 2030745
說明
對於 50%的數據有 1 ≤ Ki ≤ 10^5, 對於 100%的數據有 1 ≤ Ki ≤ 10^9, T ≤ 50it
二分答案以後反演一下能夠 O(sqrt(N)) 計算 μ^2 的前綴和。io
#include<bits/stdc++.h> #define maxn 300000 #define ll long long using namespace std; int zs[maxn/2],t=0,miu[maxn+5]; bool v[maxn+5]; inline void init(){ miu[1]=1; for(int i=2;i<=maxn;i++){ if(!v[i]) zs[++t]=i,miu[i]=-1; for(int j=1,u;j<=t&&(u=zs[j]*i)<=maxn;j++){ v[u]=1; if(!(i%zs[j])) break; miu[u]=-miu[i]; } } } inline ll calc(ll x){ ll an=0; for(int i=1;i*(ll)i<=x;i++) an+=miu[i]*(x/(i*(ll)i)); return an; } int main(){ init(); int T,n; ll l,r,mid,ans; scanf("%d",&T); while(T--){ scanf("%d",&n); l=1,r=1e11; while(l<=r){ mid=l+r>>1; if(calc(mid)>=n) ans=mid,r=mid-1; else l=mid+1; } printf("%lld\n",ans); } return 0; }