P4318 完全平方數
阿新 • • 發佈:2020-07-24
計算第\(K\)個不含完全平方因子的數。
利用容斥原理,計算時,需要減去\(2^2,3^2,5^2...\),加上\(6^2,10^2,15^2...\),減去\(30^2...\)
即,
$ans(n) =n\ -\ $含\(1\)個質因子平方的數 \(+\) 含\(2\)個質因子平方的數 \(-\) 含\(3\)個質因子平方的數\(...\)
可以看出,容斥係數即為\(\mu(i)\).
當\(i^2>n\)時,個數\(\dfrac{n}{i^2}=0\),顯然列舉的上界為\(\sqrt n\)。
不需要整除分塊。
\[ans(n)=\sum_{i=1}^{i\le \sqrt n}\mu(i)\lfloor \frac{n}{i^2}\rfloor \]
二分答案,檢查是否有\(ans(mid) > K\)。
注意:
這道題很多地方沒有給確定的範圍,所以最好一開始把陣列開的大一點,估算不出來的話就試一試...
code
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #define MogeKo qwq using namespace std; #define int long long const int maxn = 5e4+10; const int N = 5e4; int T,k,ans,cnt; int prime[maxn],mu[maxn]; bool vis[maxn]; void Prime(){ mu[1] = 1; for(int i = 2;i <= N;i++){ if(!vis[i]){ prime[++cnt] = i; mu[i] = -1; } for(int j = 1;j <= cnt && i*prime[j] <= N;j++){ vis[i*prime[j]] = true; if(i % prime[j] == 0) break; mu[i*prime[j]] = -mu[i]; } } } bool check(int x){ int sum = 0; for(int i = 1;i*i <= x;i++) sum += mu[i] * (x/(i*i)); return sum >= k; } signed main(){ scanf("%lld",&T); Prime(); for(int i = 1;i <= T;i++){ scanf("%lld",&k); int l = 1,r = k<<1; while(l <= r){ int mid = (l+r)/2; if(check(mid)){ ans = mid; r = mid-1; } else l = mid+1; } printf("%lld\n",ans); } return 0; }