线性筛与积性函数

线性筛

最初,线性筛只是用来筛质数罢了。。。

void sieve(int n) {
  static int v[N], p[N], pr;
  // v[i] 表示 i 的最小质因子
  // p[N] 和 pr 用来存质数表
  for (int i = 2; i <= n; ++i) {
    if (v[i] == 0) v[i] = i, p[++pr] = i;
    // 没被筛,是质数
    for (int j = 1; j <= pr && i*p[j] <= n; ++j) {
      v[i*p[j]] = p[j];
      if (i % p[j] == 0) break;
      // 当 i 是 p[j] 的倍数时 break
    }
  }
}

代码简短,便于记忆。。。
but,为什么复杂度是线性的呢?

  • 在筛的过程中,上面的程序将\(i\times p[j]\)的最小质因子定为\(p[j]\)。
  • 先不考虑其正确性,将\(i\)唯一分解,得到\(i=p_1^{c_1} \times p_2^{c_2} \times \cdots \times p_k^{c_k}(p_1\leq p_2 \leq \cdots \leq p_k)\)。
  • 而此时一定有\(p[j]\leq p_1\),因为当\(p[j]=p_1\)时就已经break了。
  • 同样由于\(p[j]\leq p_1\),\(i \times p[j]\)的最小质因子显然为\(p[j]\)。

然鹅还是没有证明复杂度是线性的。。。

  • 考虑每个数\(x\)被筛到的原因。
  • 若\(x\)为质数,则\(x\)被筛是理所当然的。
  • 若\(x\)非质数,则\(x\)只会被其最小质因子筛到。

所以,每个数会且仅会被筛一次,故时间复杂度为\(O(n)\)。

原文地址:https://www.cnblogs.com/yydyz/p/10441165.html

时间: 2024-10-07 20:28:29

线性筛与积性函数的相关文章

读贾志鹏《线性筛法与积性函数》笔记

1.欧拉筛法在线性时间内求素数以及欧拉函数 代码: 1 procedure get; 2 var i,j,k:longint; 3 begin 4 tot:=0; 5 fillchar(check,sizeof(check),false); 6 for i:=2 to n do 7 begin 8 if not(check[i]) then 9 begin 10 inc(tot); 11 p[tot]:=i; 12 fai[i]:=i-1; 13 end; 14 for j:=1 to tot

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

蒟蒻以欧拉心算为例子,浅谈一下如何求一些较复杂的积性函数 欧拉心算: \[\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)}\

数论 - 线性筛法与积性函数

首先以求1000000以内的素数为例来探讨筛法 Eratosthenes筛法(埃拉托斯特尼筛法) 时间复杂度:O(N*loglogN) 空间复杂度:O(N) 代码: #include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bit

积性函数筛法

积性函数筛法 很多常用的数论函数都是积性函数,而在题目中,我们常常需要线性(甚至更高)的筛法. 对于积性函数,我们可以在筛素数的基础上稍加修改,即可完成线性筛. 首先,注意到积性函数的特点: \[ f(xy)=f(x)\times f(y) \] 而可以线性筛的积性函数,需要知道以下两个式子的快速求法: \[ f(p)=?\quad f(p^k)=?\\p\in prime \] 其中, \(f(p)\) 大多是直接定义,\(f(p^k)\) 大多是递归定义. 我们来回忆一下素数筛的过程: in

线性筛及其扩展-积性函数

线性筛 埃氏筛 对于每个数x,枚举其倍数,将kx筛去. 在埃氏筛过程中,每个数都会被筛掉多次,且对于每个数x,枚举其倍数的次数为\(\frac{n}{x}\) 故埃氏筛的时间复杂度为\(\sum_{i=1}^{n}\)\(\frac{n}{i}\)=n\(\sum_{i=1}^{n}\)\(\frac{1}{i}\)=\(n ln(n)\) 欧拉筛 在埃氏筛中,每个数会被筛掉多次,想要进一步下降复杂度,我们要求每个数只会被筛一次. 要想将多种筛去x的方法固定(唯一).我们就要采用一种方法-"最小

积性函数,线性筛入门 HDU - 2879

HDU - 2879HeHe 题意:He[N]为[0,N−1]范围内有多少个数满足式子x2≡x (mod N),求HeHe[N]=He[1]×……×He[N] 我是通过打表发现的he[x]=2k,k为x是质因子个数,不过这是可以通过积性函数证明的. 关于积性函数的定义: 对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时,f(ab)=f(a)f(b),在数论上就称它为积性函数.若对于某积性函数 f(n) ,就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性

bzoj 2693: jzptab 线性筛积性函数

2693: jzptab Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 444  Solved: 174[Submit][Status][Discuss] Description Input 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M Output T行 每行一个整数 表示第i组数据的结果 Sample Input 1 4 5 Sample Output 122 HINT T <= 10000 N, M<=10000000

常用积性函数的线性筛法整理

简单整理推导加代码,留复习用. 线性筛素数 最简单也最基础,直接看代码就好了\(--\) code: void Euler_Phi_Prime(int n) { is_prime[1] = true; for (int i = 2; i <= n; i++) { if (!is_prime[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { is_prime[i * pri

bzoj 4407 于神之怒加强版 —— 反演+筛积性函数

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4407 推导如这里:https://www.cnblogs.com/clrs97/p/5191506.html 然后发现 \( F(D) \) 是一个积性函数,可以筛质数的同时筛出来: 首先,单个质数 \( p \) 时只有 \( d=1 \) 和 \( d=p \) 两个因数,所以 \( F[p] = p^{k} - 1 \) 然后如果筛到互质的数,直接把 \( F() \) 相乘即可: