題意:求第k個無平方因子數是多少ios
無平方因子數(square-free number),即質因數分解以後全部質因數的次數都爲1的數ide
膜拜Po姐姐函數
二分答案 設二分後值爲x 咱們考慮前x個數中是否含有超過k個不是平方因子的數spa
咱們考慮平方因子必定含有至少一個質數的平方 debug
那麼考慮容斥,即質數平方個數爲0的數的個數-質數平方個數爲1的數的個數+質數平方個數爲2的數的個數-……code
公式表示的話 設有p個素數並且選擇了i個素數是平方,且任選i個素數的乘積爲d,獲得公式blog
$f(x)=\sum_{i=0}^{p}(-1)^i \lfloor \frac{n}{d^{2}} \rfloor(d爲任意i個素數相乘的積)$ip
發現d最多選擇到$\sqrt{ n }$ 那麼咱們能夠考慮直接枚舉d 因而問題變成了如何快速判斷d的貢獻get
莫比烏斯函數便是。string
而後根據莫比烏斯函數的定義式,將式子化爲$f(x)=\sum_{d=1}^{\sqrt{x}} \mu (d) \lfloor \frac{n}{d^{2}} \rfloor $
因此咱們枚舉根號n內的全部答案 帶入計算便可 複雜度$O(\sqrt{n}log{n})$
/*To The End Of The Galaxy*/ #include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<iomanip> #include<bitset> #include<stack> #include<map> #include<set> #include<cmath> #include<complex> #define debug(x) cerr<<#x<<"="<<x<<endl #define INF 0x7f7f7f7f #define llINF 0x7fffffffffffll #define P(x,y) (((x-1)*c)+y) using namespace std; typedef pair<int,int> pii; typedef long long ll; inline int init() { int now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } inline long long llinit() { long long now=0,ju=1;char c;bool flag=false; while(1) { c=getchar(); if(c=='-')ju=-1; else if(c>='0'&&c<='9') { now=now*10+c-'0'; flag=true; } else if(flag)return now*ju; } } int n=100000,prime[100005],cnt,mu[100005]; bool vis[100005]; void getmu() { mu[1]=1; for(int i=2;i<=n;i++) { if(!vis[i]) { vis[i]=1; mu[i]=-1; ++cnt;prime[cnt]=i; } for(int j=1;j<=cnt&&prime[j]*i<=n;j++) { vis[i*prime[j]]=1; if(i%prime[j]==0) { mu[i*prime[j]]=0; break; } mu[i*prime[j]]=-mu[i]; } } } #define mid ((l+r)>>1) int cas; ll l,r; ll calc(ll x) { ll res=0; for(int i=1;i*i<=x;i++) { res+=x/(i*i)*mu[i]; } return res; } int main() { cas=init(); getmu(); int k; ll ans; for(int i=1;i<=cas;i++) { k=init(); l=1,r=k*2; while(l<=r) { if(calc(mid)>=k) { ans=mid; r=mid-1; } else l=mid+1; } printf("%lld\n",ans); } return 0; }