<span>质数</span>

质数的概念:大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
注:1即不是质数也不是合数

1.试除法判定质数

//判断一个数n是否是素数
bool isPrime(int n)
{
     for(int i=2;i<=n/i;i++)
   {
          if(n%i==0)
             return false;
   }
   return true;
}

2.朴素筛法求素数

int prim[N],cnt=0;     //prim[]存储所有的素数
bool st[N];            //判断st[x]是否被筛掉
void get_Prime()
{
    //循环里面需要做两件事
    //1.如果i还没有被筛掉,那么i就是素数,并用prim数组来存储他。
    //2.如果i的倍数小于等于N的话,将i的倍数都给筛掉
   for(int i=2;i<=N;i++)
   {
       if(!st[i])//数字i还没有被筛掉的情况下,i就是素数
       {
           prim[cnt++]=i;
       }
       for(int j=i*i;j<=N;j+=i)
           st[j]=true;
   }
}
//通过以上函数,我们就得到了一张2-N的素数表

线性筛法求素数

  • 任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。其中最小的质数称为该数的最小质因数。
int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j]*i <= n ; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

1.对于visit[i*prime[j]] = 1 的解释: 这里不是用i的倍数来消去合数,而是把 prime里面纪录的素数,升序来当做要消去合数的最小素因子。
2.对于 i%prime[j] == 0 就break的解释 :当 i是prime[j]的倍数时,i = kprime[j],如果继续运算 j+1,i * prime[j+1] = prime[j] * k prime[j+1],这里prime[j]是最小的素因子,当i = k * prime[j+1]时会重复,所以才跳出循环。
举个例子 :i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。因为欧拉筛法的原理便是通过最小素因子来消除。

试除法分解质因数:

void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            while (x % i == 0) x /= i, cout<<i<<' '; ;
        }
    if (x > 1) cout << x << ' ' << endl;
    cout << endl;
}

eg:
给你两个整数L,R求区间[L,R]中相邻的两个质数的差值最大是多少(L,R<=2^31 ,R-L<=\(10^6\))
解析:

参考资料:
1.https://blog.csdn.net/qq_39763472/article/details/82428602

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务