埃及筛素数+欧拉筛函数

线性筛素数:

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的最小因子。
const int maxn = 10010, INF = 0x7fffffff;
int prime[maxn+1];
void get_prime()
{
    mem(prime, 0);
    for(int i=2; i<=maxn; i++)
    {
        if(!prime[i]) prime[++prime[0]] = i;
        for(int j=1; j<=prime[0] && prime[j] <= maxn/i; j++)
        {
            prime[prime[j]*i] = 1;
            if(i % prime[j] == 0) break;
        }
    }
}

线性欧拉函数

   该算法在可在线性时间内筛素数的同时求出所有数的欧拉函数。

    需要用到如下性质(p为质数):

    1. phi(p)=p-1   因为质数p除了1以外的因数只有p,故1至p的整数只有p与p不互质

    2. 如果i mod p = 0, 那么phi(i * p)=p * phi(i)  证明如下

    (上述证明存在bug。。感谢@PrimaryOIer指教)

    上面的过程证明了从区间[1,i]->[i+1,i+i],若整数n不与i互质,n+i依然与i不互质。下面给出另一个证明:若整数n与i互质,n+i与i依然互质

    3.若i mod p ≠0,  那么phi(i * p)=phi(i) * (p-1)

        i mod p 不为0且p为质数, 所以i与p互质, 那么根据欧拉函数的积性phi(i * p)=phi(i) * phi(p) 其中phi(p)=p-1即第一条性质

const int maxn = 10010;
int prime[maxn], phi[maxn];
bool vis[maxn];
int ans;
void get_prime()
{
    ans = 0;
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i < maxn; i++)
    {
        if(!vis[i]) prime[++ans] = i;
        for(int j = 1; j <= ans && prime[j] * i < maxn; j++)
        {
            vis[i * prime[j]] = 1;
            if(i % prime[j] == 0) break;
        }
    }
}

void get_phi()
{
    ans = 0;
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i < maxn; i++)
    {
        if(!vis[i]) prime[++ans] = i, phi[i] = i - 1;
        for(int j = 1; j <= ans && prime[j] * i < maxn; j++)
        {
            vis[i * prime[j]] = 1;
            if(i % prime[j] == 0)
            {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            else
                phi[i * prime[i]] = phi[i] * (prime[j] - 1);
        }
    }
}

时间差距

when n = 10000
    eratosthenes_sieve(1229):     0(us)
    euler_sieve(1229):            0(us)
when n = 100000
    eratosthenes_sieve(9592):     999(us)
    euler_sieve(9592):            0(us)
when n = 1000000
    eratosthenes_sieve(78498):    13004(us)
    euler_sieve(78498):           7004(us)
when n = 10000000
    eratosthenes_sieve(664579):   185130(us)
    euler_sieve(664579):          79067(us)
when n = 100000000
    eratosthenes_sieve(5761455):  2363692(us)
    euler_sieve(5761455):         842592(us)
when n = 1000000000
    eratosthenes_sieve(50847534): 25535159(us)
    euler_sieve(50847534):        8987385(us)
转载自大佬们
https://www.cnblogs.com/Miroerwf/p/7776390.html
https://blog.csdn.net/Lytning/article/details/24432651
https://blog.csdn.net/codertcm/article/details/82902978
 
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
原文地址:https://www.cnblogs.com/WTSRUVF/p/9575648.html