线性筛法相关

原创 2016年06月01日 14:54:38

基本证明可以看这里,懒得多写。
一个藓的证明
最关键部分
(iU)=P1P2P3...Pm1PmU(U>P1)
=UP2P3...Pm1PmP1
=i'P1(i'>i) 且i’与P1互质.

其实还可以筛其他东西
他们的本质都是要求的ix的值与最小质因子x有关系.
下面所有的分析与证明都要与线性筛法代码结合,不然读不懂.

筛出约数个数

dh写的
首先吧,肯定要维护这个玩意Ansii有多少约数
然后再维护一个Ei表示i的最小质因子的指数 (因为线筛的本质就是每个数只会被他最小的质因子筛去)
*Ansi=(a1+1)(a2+1)...(at+1) 其中ai表示第i个质因数的指数。

还有一个质数表p.
那我们来分类讨论一下。
ipj=k,

i mod pj!=0时,

pj是k的最小质因子,且这个质因子指数为1,这个由线筛的基本证明可以得到。
就说明k相对于i多了一个质因子pj
Ansk=Ansi(Epj+1)
Ek=1
其中Epj=1,因为pj是质数。

i|pj时,

pj同样是k的最小质因子,但指数不为1,这个是废话。
就说明k相对于i又多了一个质因子pj,不难推出:
Ek+=1
Ansk=Ansk/Ek(Ek+1)

于是我们就完成了这个艰巨的任务: 筛出每个数有多少约数。

void get_prime()  
{  
    int i,j,k;  
    memset(flag,false,sizeof(flag));  
    k=0;  
    for(i=2;i<M;i++){  
        if(!flag[i]){                              
                prime[k++]=i;  
                e[i]=1;  
                Ans[i]=2;                       //素数的约数个数为2  
            }  
            for(j=0;j<k&&i*prime[j]<M;j++){  
                    flag[i*prime[j]]=true;              
                    if(i%prime[j]==0){  
                        Ans[i*prime[j]]=Ans[i]/(e[i]+1)*(e[i]+2);  
                        e[i*prime[j]]=e[i]+1;  
                        break;  
                    }  
                    else{  
                        Ans[i*prime[j]]=Ans[i]*Ans[prime[j]];  
                        e[i]=1;  
                    }  
            }  
        }  
}  

筛出欧拉函数φ

读作φ(fai1),写作phi
φ(n)为小于等于n并与n互质的数的个数,他是积性函数 φ(a*b)=φ(a)*φ(b),gcd(a,b)=1

一个性质:
显然当x是素数时φ(x)=x1,
φ(xk)=xkxkx=xk1(x1)
因为显然只有有x这个因子的数(x的倍数)才不互质xk

现在我们来考虑一个数
由积性函数得,φ(x)=φ(p1a1)φ(p2a2)....φ(pkak)
pj为x的第j个质因子,aj为其对应的指数.
那我们之前得的那一个性质就有用了.
设x为i的第1个质因子(任意一个也可,这里方便表述),则

φ(xk)=xk1(x1)得,
φ(xk+1)=xk(x1).
φ(xk+1)=φ(xk)x

φ(xi)
=φ(xa1+1)φ(p2a2)....φ(pkak)
=xφ(xa1)φ(p2a2)....φ(pkak)
=xφ(i)

结论
x是素数,
φ(ix)=φ(i)xx|i
否则φ(ix)=φ(i)φ(x)=φ(i)(x1)由积性函数得

int prime[M/3],phi[M];  
bool flag[M];  
void get_prime()  
{  
    int i,j,k;  
    memset(flag,false,sizeof(flag));  
    k=0;  
    for(i=2;i<M;i++){  
        if(!flag[i]){                              
            prime[k++]=i;  
            phi[i]=i-1;  
        }  
        for(j=0;j<k&&i*prime[j]<M;j++){  
            flag[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);  
        }  
    }  
}
版权声明:未经作者本人允许禁止转载。

相关文章推荐

数论学习笔记 欧拉函数 (一些性质和运用)内置杜教筛

定义在数论中,对正整数n,欧拉函数是小于等于n的数中与n互质的数的数目。并且用符号φ(n)\varphi(n)表示一个整数的欧拉函数。例如φ(8)=4\varphi(8) = 4。特殊的φ(1)=1\...

数学模板-欧拉函数

欧拉函数
  • YJSchaf
  • YJSchaf
  • 2017年04月01日 11:53
  • 1412

线性筛法

又重新统一了下线性筛法模版 void linear_prime(int wt)//线性筛法筛质数 {    for(int i = 2; i ...

线性筛法求解 H数列问题

Description 有一组数列,1, 5, 9, 13, 17, 21,25...,(都模4余1),叫做H数列。 可以把H数列中的数分为三种 (1)H-素数:h是H-素数,把h是分解成两...
  • ljd4305
  • ljd4305
  • 2012年08月25日 11:17
  • 1405

线性筛法 gcd 快速幂

线性筛法、gcd、快速幂[介绍]今天特地学了下线筛,感觉棒棒哒。。。线性筛法,顾名思义,就是每个数筛一遍,即每个合数只标记一次,我们知道,一个合数可以写成一个素数和一个数的乘积的形式,而要想每个数筛一...
  • Yancy_
  • Yancy_
  • 2017年01月31日 22:25
  • 209

【BZOJ 2818】 gcd(附φ的线性筛法预处理)

Description 给定整数N,求1

线性筛法(欧拉筛)

从前有一个素数筛法叫埃拉托斯特尼筛法,它的思想很简单,把1-n以内素数的整数倍的数字划掉,留下的就全是素数,但是它的复杂度是O(NlglgN),对于大量不友好数据会跪,于是线性晒登场了。 #inclu...
  • zjq_01
  • zjq_01
  • 2017年06月02日 19:30
  • 154

欧拉函数线性筛法详解

该算法在可在线性时间内筛素数的同时求出所有数的欧拉函数。
  • Lytning
  • Lytning
  • 2014年04月24日 19:52
  • 5141

素数筛法 埃氏筛 线性筛

素数筛法? 呃~,太暴力的试1~sqrt(n)时候是因数就不说了。 这里介绍埃氏筛和线性筛。埃氏筛埃氏筛主要原理是: 每次搜索到一个质数将他的倍数标记为合数; 本质原理就是:一个合数一定表示为...
  • sdfzsyh
  • sdfzsyh
  • 2017年07月06日 22:10
  • 188

【jzoj4860】【分解数】【线性筛法】

题目大意给出一个数,每次可以分成两个互质的数,求可以分解多少次。解题思路其实就是求不同的质因子个数,可以用线筛求出每个数的前驱来分解质因数,因为卡空间所以要牺牲时间来换空间少存一些值。code#inc...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线性筛法相关
举报原因:
原因补充:

(最多只允许输入30个字)