线性筛法与欧拉函数

线性筛法与欧拉函数

标签(空格分隔): 数论


一、引入

我们已经很熟悉Eratosthenes筛法(埃拉托斯特尼筛法),其基本思想是,每次筛去一个指数的所有倍数,如对于质数2,筛去4,6,8等等,对于质数3,筛去6,9,12等等。
其弊端也显而易见,6和12等等数字,均被筛去的多次,这样就造成了重复,复杂度不够好。
有没有更快的筛法,当然有。

二、说在前面

对于任何一个数字,我们都能利用唯一分解定理将其拆分。对于合数来说,其因子数量大于等于2个,如最小的合数4可以拆分为2*2 , 6可以拆分为2*3.
于是对于任何的合数 n ,我们用以下的方法进行表示:

n=pminp

其中 pmin n 的最小质数。例如12=26 而不是 12=34 ,因为2是12最小的质因数, 18=29 也是这个道理。

如此的规定不是无故为之的,如果每个合数都被其最小的质因数筛去,那么就会保证不重不漏。换言之,若我们对于质数2,将所有以2为最小质因数的合数筛去,对于质数3,将所有以2为最小质因数的合数筛去,如此就可以保证不会重复筛一个数。
如何实现呢?

三、代码实现

memset(check,false,sizeof check);
int tot = 0;
for(int i = 2;i<=N;++i) {
    if(!check[i]) prime[tot++] = i;
    for(int j = 0;j<tot;++j) {
        if( i * prime[j] > N ) break;
        check[ i * prime[j] ] = true;
        if( i % prime[j] == 0 ) break;
    }
}

其中第八行的if( i % prime[j] == 0 ) break;可谓精髓。
可以见得? 当i为4时,首先筛掉的是8,而此时 i % 2等于0,跳出内层循环,否则的话,就会筛掉12,而我们知道,12应该在因子为2的时候筛掉,而不是3的时候被筛掉,这样一来保证了复杂度。

四、欧拉函数

欧拉函数指的是:对一个正整数 n ,小于n且与 n 互质的数的个数,用符号φ(n)来表示
φ(24)=8 ,因为1, 5, 7, 11, 13, 17, 19, 23均和 24 互质。

下面介绍一些基本性质:
其中加**表示在求欧拉函数的时候会用得到。
1. n1,φ(1)=1
2. **当 n 为质数的时候,φ(n)=n1
3. **欧拉函数是积性函数,但不是完全积性。当 n,m 互质的时候, φ(nm)=φ(n)φ(m)
4. 当n为奇数的时候, φ(2n)=φ(n)
5. 除了 φ(2) 时,其他欧拉函数均为偶数。
6. 小于 n ,且与n互质的所有数字的和是 φ(n)n/2

可以在线性筛法中,加入求欧拉函数的内容。

五、代码拓展

memset(check,false,sizeof check);
int tot = 0;
phi[1] = 1;
for(int i = 2;i<=N;++i) {
    if(!check[i]){
        prime[tot++] = i;
        phi[i]= i-1;    
    }
    for(int j = 0;j<tot;++j) {
        if( i * prime[j] > N ) break;
        check[ i * prime[j] ] = true;
        if( i % prime[j] == 0 ) {
            phi[ i * prime[j] ] = phi[i] * prime[j] ;
            break;
        }else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
    }
}

第7行参考性质2
第15行参考性质3
好好理解一下第13行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值