数论—质数

1.\(对于一个足够大的整数N,不超过N的质数大约有N/lnN个,即每lnN个数中大约有1个质数.\)

2.\(约数总是成对出现的,如果M|N,则\frac{N}{M}|N.\)

  • 试除法判定质数
bool is_prime(int n)
{
  for(int i=2;i<=n/i;i++)
       if(n%i==0)return flase;
  return true;
}
  • 筛质数:\(给定整数N,求出1\sim{N}之间所有的质数\)

1.埃氏筛法

原理:
\(任意整数X的倍数都不是质数.\)
证明:
\(对于2<=P<=N,如果P最后没有被筛掉,则P不是{2}\sim{P-1}中任何一个数的倍数,\)
\(同理2\sim{P-1}没有一个数是P的约数,根据质数定义,P是质数\)

\(复杂度O(loglog N)\)

int cnt,primes[N],st[N];
void f(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(st[i])//如果不是质数
        continue;
        primes[cnt++]=i;
        for(int j=i+i;j<=n;j+=i)//只筛质数的倍数
        st[j]=1;
        /*
        更快一些的写法
        for(int j=i;j<=n/i;j++)等价于for(int j=i;j*i<=n;j++)在整数N范围内对质数的倍数进行标记
        st[j*i]=1;*/
    }
}

2.线性筛法

核心
\(每个合数只会被它的最小质因子筛掉,保证了时间复杂度是O(N)\)
\(例如6在\underline{埃氏筛}中会被2,3筛两次,\underline{线性筛}中希望6(合数)只被2筛一次\)

const int N=1e6+10;
int cnt,n,p[N],st[N];
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        if(!st[i])p[cnt++]=i;
        for(int j=0;j<cnt&&p[j]<=n/i;j++)
        {
            st[i*p[j]]=1;
            if(i%p[j]==0)break;
        }
    }
    cout<<cnt;
  • 质因数分解:

1.算术基本定理

\(任何一个大于1的正整数都能唯一分解为有限个质数的乘积:\)
\( N=p_1^{c_1}p_2^{c_2}...p_m^{c_m} \\其中c_i都是正整数,p_i都是质数,且满足p_1<p_2<...<p_m. \)

2.重要定理

\( 对于整数N,最多只有一个大于\sqrt{N}的质因子 \\ 反证法:如果N有多个大于\sqrt{N},那么他们的乘积>N,矛盾 \)

void f(int k)
{
    for(int i=2;i<=k/i;i++)
    {
        int cnt=0;
        if(k%i==0)//i一定是质数,因为有下面的while循环,对于K来说
        {         //K的合数因子一定在扫描到这个合数之前就被质数从K中除掉了
                  //所以能整除K的一定不是合数。
            cout<<i<<" ";
            while(k%i==0)
            {
                cnt++;
                k/=i;
            }cout<<cnt<<endl;
        }
    }
    if(k>1)
    cout<<k<<" "<<"1"<<endl;
    puts("");
}
posted @ 2020-07-09 15:23  30天CF上蓝!!!  阅读(125)  评论(0编辑  收藏  举报