题解 P3912 【素数个数】
我来一发 Min25 筛的题解!
(其实已经有一个大佬发了但是没什么解释
Min25 筛算法中有一个过程就是求
那么如果我们构造
(其实洲阁筛也有这一部分而且做法是一样的
设
其实就是埃筛
考虑转移。
若
若
注意到这样子会减去
整理一下可得
答案即
观察转移式易得实际上用到的
复杂度被证明为
代码:
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 1e8;
const int MX = 1e4;
int n;
int lim;
int vis[MX + 5],cnt,prime[MX + 5];
int lis[2 * MX + 5];
int tot,le[MX + 5],ge[MX + 5];
int G[2 * MX + 5];
inline int &id(long long x)
{
return x <= lim ? le[x] : ge[n / x];
}
int main()
{
for(register int i = 2;i <= MX;++i)
{
if(!vis[i])
prime[++cnt] = i;
for(register int j = 1;j <= cnt && i * prime[j] <= MX;++j)
{
vis[i * prime[j]] = 1;
if(!(i % prime[j]))
break;
}
}
scanf("%d",&n),lim = sqrt(n);
for(register long long l = 1,r;l <= n;l = r + 1)
{
r = n / (n / l);
lis[id(n / l) = ++tot] = n / l;
G[tot] = n / l - 1;
}
for(register int k = 1;k <= cnt;++k)
{
int p = prime[k];
long long s = (long long)prime[k] * prime[k];
for(register int i = 1;lis[i] >= s;++i)
G[i] -= G[id(lis[i] / p)] - (k - 1);
}
printf("%d\n",G[1]);
}