码迷,mamicode.com
首页 > 其他好文 > 详细

线性筛与积性函数

时间:2019-02-27 01:02:55      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:代码   static   math   time   line   证明   因子   code   个数   

线性筛

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

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)\)

线性筛与积性函数

标签:代码   static   math   time   line   证明   因子   code   个数   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!