欧拉筛法

来源:互联网 发布:联通数据关闭还走流量 编辑:程序博客网 时间:2024/05/16 12:02

素数筛法
1、智障型
对每个数都循环一次
复杂度gg
昨天实测10000内要5-6秒才能输完

2.开方型
一般新手的标配

3.埃拉托斯特尼筛法
有人随缘想到的方法
对于每个质数都将其倍数标记
如果已经被标记的就不去循环
复杂度nloglogn
蜜汁复杂度
理论上nloglogn是近似认为是n的

4.欧拉筛法
针对每个数只被标记一次
不重复标记
并不显著减小复杂度
复杂度是n

int main(){    freopen("out1.out","w",stdout);        for(int i=2;i<=100000;i++){        if(!check[i]) prime[++cnt]=i;        for(int j=1;j<=cnt;j++){            if(i*prime[j]>100000) break;            check[i*prime[j]]=1;            if(i%prime[j]==0)//这里写成i==prime[j]可以减小复杂度                 break;        }    }    for(int i=1;i<=100000;i+=1)        if(!check[i]) printf("%d",i);}

关于我看到别人写的都是i%prime[j]==0
但是我对拍了100000的数据发现一样
但是在计算机 当中取模好像很慢所以似乎可以写成判断相等

注意:数据大时输出的时间可能超越算法本身很多倍
ps:听说计算时计算机可以并行运算
下面粘一些线性筛的板子

线性筛逆元
无法理解的东西
代码就一句话

inv[i]=(p-p/i)*inv[p%i]%p

为什么这么写我也不知道记住就好了

线性筛欧拉函数

void prime (int n){    int cnt = 0 ;    memset( vis, 0 ,sizeof(vis));    for(register int i=2;i<=n;i++)    {        if(!vis[i])        {            prime[++cnt]=i;            phi[i]=i-1;            }            for(register int j=1;i*prime[j]<n;j++){                long long k=i*prime[j];                vis[k]=1;                if(i%prime[j]==0)                {                    phi[k]=phi[i]*prime[j];                    break;                }                else                 phi[k]=phi[i]*(prime[j]-1);            }        }    }}

对于积性函数都可以线性时间筛出来

2 0
原创粉丝点击