欧拉素数筛据说它是一个线性筛,时间复杂度接近于O(n),可惜我不会证明。
裸的欧拉素数筛模板
bool isprime[numsize];
int prime[numsize];
memset(isprime, 1, sizeof(numsize));
isprime[1] = false;
int cnt = 1;
for(int i = 2; i <= numsize; i ++)
{
if(isprime[i])
{
prime[cnt ++] = i;
}
for(int j = 1; j < cnt&&prime[j]*i <= numsize; j ++)
{
isprime[i*prime[j]] = false;
if(i%prime[j] == 0)//1
break;
}
}
1处解释:prime[]数组中的素数是递增的,当i能整除prime[j],那么i*prime[j+1]这个合数肯定被prime[j]乘以某个数筛掉。 因为i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那么i*prime[j+1]=(k*prime[j])*prime [j+1]=k’*prime[j],接下去的素数同理。所以不用筛下去了。因此,在满足i%prime[j]==0这个条件之前以及第一次 满足改条件时,prime[j]必定是prime[j]*i的最小因子。
该题可以说是素数筛的变形,即在筛素数的同时,记录下最大质因子的位置。
1522.陆历川学数学
Description
陆历川很热爱数学,最近他学了质数,他被质数深深的吸引了,但是陆历川有个习惯,他喜欢给一些东西编号,所以他决定给所有的质数编号,例如给2编号1,3编号2,5编号3........这样2,3,5就是质数里面的大当家,二当家和三当家了,陆历川现在知道了这些编号,现在他会给你一个数,他想知道这个数的所有的质因子里面的最大编号是多少?
注:0和1的编号都是0。
Input
一个自然数N(0<= N <= 1000000)
多组输入样例
Output
最大编号
Sample Input
1 2 3 4 5
Sample Output
01213
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct isprime
{
int num;
bool is;
}isprime[1000005];
int prime[1000005];
int main()
{
memset(isprime, 0, sizeof(isprime));
memset(prime, 0, sizeof(prime));
int n;
int cnt = 1;
prime[0] = 1;
isprime[1].is = 0;
isprime[1].num = 0;
for(int i = 2; i <= 1000005; i ++)
{
if(!isprime[i].is)
{
prime[cnt ++] = i;
isprime[i].num = cnt - 1;
}
for(int j = 1; j < cnt&&i*prime[j]<1000005; j ++)
{
isprime[i*prime[j]].is = 1;
if(isprime[i].num > j)
isprime[i*prime[j]].num = isprime[i].num;
else
isprime[i*prime[j]].num = j;
if(i%prime[j] == 0)
{
break;
}
}
}
while(scanf("%d", &n)!=EOF)
{
if(n == 0)
{
printf("0\n");
continue;
}
printf("%d\n", isprime[n].num);
}
return 0;
}