线性筛--如何线性求约数个数

线性筛

我已经掌握埃氏筛了 为什么还要学线性筛???

线性筛的时间复杂度是严格 \(O(N)\) 的, 而埃氏筛的复杂度是 $ O(N * log_{2}( log_{2}(N) ) $

看上去并没有快多少 实际也是, 但在处理一些大数据时,差距就凸显出来了

算法思路

概述:

和埃氏筛类似的

线性筛是通过枚举到的当前数字乘以某个比该数的最小质因子还小的质数来筛的

(上面这句话有点长, 需要反复理解 暂时不能理解,也没关系,等下代码中我会详细讲的)

这样就可以保证每次几乎不会出现重筛的情况,大大减少了循环次数

代码:
#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define in inline
#define get getchar()
int read()
{
    int t=0; char ch=get;
    while(ch<'0' || ch>'9') ch=get;
    while(ch<='9' && ch>='0') t=t*10+ch-'0',ch=get;
    return t;
}
const int _=1e7+6;
int prime[_], tot, n; //tot是素数个数,prime是从小到大存放的素数数组
bool flag[_];//用来判断当前数已为素数,flag==1不是素数
int main()
{
    n=read();
    for (re int i=2;i<=n;i++)
    {
        if (!flag[i]) prime[++tot]=i; // 当前数没有被打上非素数标记
        for (re int j=1;j<=tot&&prime[j]*i<=n;j++)
        {      //保证prime[j]在已确定的素数范围内
            flag[prime[j]*i]=1; //打上非素数标记
            if(i%prime[j]==0) break; //若当前prime[j]已是i的约数
            //剩下的不用重复处理,所以直接break
        }
    }
    cout<<"TOT:  "<<tot<<endl;
    for (re int i=1;i<=tot;i++)
        cout<<prime[i]<<' ';
    return 0;
}

用线性筛在线性时间里求1~n的约数个数

思路

记录数字 i 的最小约数出现次数 minn[i]
然后通过我们以前的知识 小学奥数 知道d(i)==(每个质因数的指数+1)的积
然后利用线性筛的性质递推 minn[i] 与 d[i] 就好

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define get getchar()
#define in inline
#define re register
const int _=10000001;
int minn[_],n,tot,prime[_],d[_];
bool np[_];
int main()
{
    cin>>n;
    d[1]=1;
    for(re int i=2; i<=n; i++)
    {
        if(np[i]==0) prime[++tot]=i,d[i]=2,minn[i]=1;
        for(re int j=1;prime[j]*i<=n&&j<=tot;j++)
        {
            np[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                minn[i*prime[j]]=minn[i]+1;
                d[i*prime[j]]=d[i]/(minn[i]+1)*(minn[prime[j]*i]+1);
                break;
            }
            minn[i*prime[j]]=1;
            d[i*prime[j]]=d[i]*2;
        }
    }
    for( re int i=1;i<=n;i++)
        cout<<d[i]<<' ';
}

原文地址:https://www.cnblogs.com/yzhx/p/11521073.html

时间: 2024-08-29 06:17:46

线性筛--如何线性求约数个数的相关文章

[线性筛][筛素数/筛约数个数]

线性筛中每个数只会被最小的素因子筛一次 1)线性筛素数 1 void getprime(int siz){ 2 memset(isprime,1,sizeof(isprime)); 3 isprime[1]=0; 4 for(int i=2;i<=siz;i++){ 5 if(isprime[i])prime[++tot]=i; 6 for(int j=1;j<=tot&&i*prime[j]<=siz;j++){ 7 isprime[i*prime[j]]=0; 8 i

线性筛合集

迟到的线性筛合集. 1.线性筛质数. 这个不讲了大家都会.不过他是下面的基础.注意每个数都是被最小质因子筛去的. 2.线性筛逆元. 这个有两种做法.第一种是质数直接用费马小定理,然后根据逆元是完全积性函数直接乘起来. 第二种直接线性递推.设\(p = ki + b\),则有\(ki + b \equiv 0 (mod\ p),b = p\ \%\ i,k = \lfloor\frac{p}{i}\rfloor\) \(b \equiv -ki (mod\ p)\)两边同乘\(inv_b,inv_

noip复习——线性筛(欧拉筛)

整数的唯一分解定理: \(\forall A\in \mathbb {N} ,\,A>1\quad \exists \prod _{i=1}^{s}p_{i}^{a_{i}}=A\),其中\({\displaystyle p_{1}<p_{2}<p_{3}<\cdots <p_{s}}\)而且 \(p_{i}\)是一个质数, \(a_{i}\in \mathbb {Z} ^{+}\)(摘自维基百科) 欧拉筛通过使每个整数只会被它的最小质因子筛到来保证时间复杂度,可以用来筛质数

线性筛素数详细整理

如果你在1个月前让我判断素数,我一定会猛敲出以下代码: bool check( int num ) { int tmp =sqrt( num); for(int i= 2;i <=tmp; i++) if(num %i== 0) return 0 ; return 1 ; //实在是太慢了! } $ $ 下面给大家带来3种筛选素数和一种直接判断素数 $ $ $ $ 什么是线性筛? 对于求多个质数时与其一个个判断不如用排除法,用空间换取大量时间. $ $ $ $ $ $ 一般筛法(埃拉托斯特尼筛法

关于在线性筛中求积性函数

蒟蒻以欧拉心算为例子,浅谈一下如何求一些较复杂的积性函数 欧拉心算: \[\sum_{i=1}^n\sum_{j=1}^n\phi(gcd(i,j))\] 与之前的一样: \[\sum_{d=1}^n\phi(d)\sum_{i=1}^{[n/d]}\sum_{j=1}^{[n/d]}[gcd(i,j)==1]\] 利用\(\mu\)函数的性质: \[\sum_{d=1}^n\phi(d)\sum_{i=1}^{[n/d]}\sum_{j=1}^{[n/d]}\sum_{k|gcd(i,j)}\

【莫比乌斯反演】【线性筛】bzoj2005 [Noi2010]能量采集

http://blog.csdn.net/Clove_unique/article/details/51089272 Key:1.连接平面上某个整点(a,b)到原点的线段上有gcd(a,b)个整点. 2.欧拉函数的性质之一:若(N%a==0 && (N/a)%a==0) 则有:phi(N)=phi(N/a)*a.由此可以线性筛. 3.一个数的所有因子的phi值之和恰好等于这个数本身. #include<cstdio> #include<algorithm> usin

bzoj 3309 DZY Loves Math——反演+线性筛

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3309 像这种数据范围,一般是线性预处理,每个询问 sqrt (数论分块)做. 先反演一番.然后 f( ) 还不能一个就花 log 的时间,所以要分析性质. 设 n 一共 m 个质因数,其中最大的指数是 t . 已有 Σ(d|n) f(d)*u(n/d) ,如果 u( ) 的部分含有指数>=2的质因子,就无贡献:所以 u( ) 里每种质因数选1个或0个,一共 2^m 种. 如果 n 里有一个

Sum of Consecutive Prime Numbers POJ - 2739 线性欧拉筛(线性欧拉筛证明)

题意:给一个数 可以写出多少种  连续素数的合 思路:直接线性筛 筛素数 暴力找就行   (素数到n/2就可以停下了,优化一个常数) 其中:线性筛的证明参考:https://blog.csdn.net/nk_test/article/details/46242401 https://blog.csdn.net/qq_40873884/article/details/79124552 https://blog.csdn.net/baoli1008/article/details/50788512

BZOJ 3994 [SDOI2015]约数个数和 (神定理+莫比乌斯反演)

3994: [SDOI2015]约数个数和 Time Limit: 20 Sec  Memory Limit:128 MB Submit: 239  Solved: 176 [Submit][Status][Discuss] Description 设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Output T行,每行一个整数,表示你所求的答案. Sample Input 2 7