数学类———素数(欧拉筛)

欧拉筛:

const int N= 1000010;

int primes[N], cnt;
bool st[N];

oid get_prime(int x) {
    for(int i = 2; i <= x; i++) {
        if(!st[i]) prime[cnt++] = i;
        for(int j = 0; prime[j] <= x / i; j++) {
            st[prime[j]*i] = true;
            if(i % prime[j] == 0) break}
    }
} 



欧拉筛的证明:

i%primes[j]==0

 1.primes[j]是i的最小质因子
 2.如果标记i*primes[j+1]......i*primes[j] 对应的最小质因子是primes[j]<primes[j+1],违反了只标记最小质因子为primes[j]的原则
 3. i*primes[j+1]应该留给 i_new=i*primes[j+1]/primes[j]去标记

i%primes[j]!=0

1:如果i是合数,那么i的最小质因子大于primes[j],i*primes[j]的最小质因子是primes[j]
2:如果i是质数,那么iprimes[j]的最小质因子就是primes[j]
3 综上i%primes[j]!=0 时,i*primes[j]的最小质因子就是primes[j]

1.综上:

1.这个代码只标记以primes[j]为最小质因子的合数n,由于一个合数n只有一个最小质因子,所以一个合数最多被标记一次

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

2.1一个合数n有且仅有一个最小质因子k1,n/k1>=k1,所以primes数组一定包含k1(因为primes数组包含小于n/k1的所有素数).
2.2对于i=n/k,primes包含k1.如果i=n/k是素数那么在primes[k0]<primes[k1]之前一定不会退出循环直到n/k%k=0,如果i=n/k是合数那么在primes[k0]<primes[k1]之前k0不是n/k1的因子(因子n/k1的最小质因子>=k1因为n的最小质因子为k1),所以n/k1%primes[k0]!=0

2.综上:

	2.3综上一个合数肯定在i=n/k1(k1为最小质因子)被标记

3.综综上:

3.由于一个合数最多被标记一次(1证),又由于一个合数一定被标记一次,所以一个合数能切仅能被标记一次时间复杂度O(n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值