bzoj 2440 完全平方数
这是一道论文题。
题意:选出第k个无平方因子的数。
思路:二分答案。
某一个区间的无平方因子的数的个数怎么求呢? 可以筛。
这里可以莫比乌斯。
首先什么是莫比乌斯函数呢?
回到本题:
他是一个莫比乌斯函数的应用。
对于1~ mid 中,不含平方因子的个数为:
n - sum(i^2) 其中 i 为素数。
含不含平方因子:就是将 N 质因数分解,只有u(n) != 0的值才是不含质因数因子的。但是开不来10^9的数组,来遍历u(n),用素数优化。
例如: 4,9,4n,9n,这些数得删掉,4的倍数的个数 为 n/4 n/9,
所谓平方因子也是 一些素数的平方得到的。
那么这里就有一个容斥定理,n - 每个质数的平方因子的数的倍数,(这里不用算素数,因为有莫比乌斯函数做系数)+每两个质数的乘积的平方因子的数的倍数-每三个... ...
例如:删掉了4的倍数,9的倍数,那么36就被删了两次,(容斥定理)
#include <bits/stdc++.h> using namespace std; const int n = 1e+5; typedef long long ll; int mu[n]; void getMu() { for(int i=1;i<=n;i++) { int target = i == 1? 1: 0; int delta = target - mu[i]; mu[i] = delta; for(int j=i+i;j<=n;j+=i) mu[j] +=delta; } } ll k; ll calc(ll mid) { ll sq = sqrt(mid); ll ans = 0; for(ll i=1;i<=sq;++i) { ans+=mu[i]*(mid/(i*i)); } return ans; } int main(int argc, char const *argv[]) { getMu(); ll t; scanf("%I64d",&t); for(ll z=0;z<t;++z) { scanf("%I64d",&k); ll l = 0,r = k*2; while(l<r) { ll mid = (l+r)/2; if(calc(mid)>=k) r = mid; else l = mid + 1; } cout<<l<<endl; } return 0; }