数论函数学习笔记之线性筛

其实主要是想发一下线性筛的板子,包括线性筛质数,约数个数,欧拉函数和莫比乌斯函数。
有些也会有一点简单的证明。


线性筛质数就不说啦。


然后加一个筛欧拉函数。
当\(i\)为质数的时候,自然\(\varphi(i) = i - 1\)。
令\(n = mp\),
当\(p \nmid m\)的时候,有\(\varphi(n) = \varphi(m) * \varphi(p) = \varphi(m) * (p - 1)\)。
否则有\(\varphi(n) = \varphi(m) * p\)。


证明一下吧:
首先\(p \nmid m\)时,根据积性,\(\varphi(n) = \varphi(m) * (p - 1)\)。
考虑另一种情况,
若\(p \mid m\),令\(m = k * p ^ x\),这样保证了\(k, p\)互质。
所以

\[\begin{align} \varphi(n) &= \varphi(k) * \varphi(p ^ {x + 1}) \\ &= \varphi(k) * p ^ x * (p - 1) \\ \end{align} \]


然后看等式右边:

\[\begin{align} \varphi(m) * p &= \varphi(k) * \varphi(p ^ x) * p \\ &= \varphi(k) * p ^ {x - 1} * (p - 1) * p \\ &= \varphi(k) * p ^ x * (p - 1) \end{align} \]

(也不知道这算不算证明)
另一种证明\(\varphi(n) = \varphi(m) * p\)的方法是把\(\varphi(n)\)和\(\varphi(m)\)相除,并用\(\varphi(n) = n * \prod_{质数p|n} (1 - \frac{1}{p})\)打开,约分后就是\(p\)了。


至于筛莫比乌斯函数,就更简单了。
如果\(n\)为质数,则\(\mu(n) = -1\)。
若\(p \mid m\),则\(\mu(n) = 0\),
否则\(\mu(n) = - \mu(m)\)。


最后是筛约数个数。
首先得知道这几个理论基础:
1.记\(n = \prod p _ i ^ {a_i}\),那么\(n\)的约数个数为\(\prod (a_i + 1)\),就是枚举每一个约数选几个。
2.线筛的时候,每一个数是被他的最小素因子筛去,如果\(prime[j] \mid i\),那么\(prime[j]\)也是\(i\)的最小素因子。


我们令\(y[n]\)表示\(n\)的约数个数,\(d[n]\)表示\(n\)的最小素因子的个数。
那么,
1.如果\(n\)为质数,显然有\(y[n] = 2, d[n] = 1\)。
2.如果\(n\)为合数,令\(n = i *prime[j]\),
  (1)如果\(prime[j] \nmid i\),那么\(d[n] = 1, y[n] = y[i] * y[prime[j]] = y[i] * 2\)(积性)。
  (2)如果\(prime[j] \mid i\),那么\(n\)和\(i\)的最小素因子都是\(prime[j]\),且\(d[n] = d[i] + 1\)。这时候算约数个数,把原来的除掉,乘以新的贡献即可:\(y[n] = y[i] * \frac{d[i] + 2}{d[i] + 1}\)。

In void init()
{
	mu[1] = ys[1] = phi[1] = 1;
	for(int i = 2; i < maxn; ++i)
	{
		if(!v[i]) 
		{
			prim[++pcnt] = i, v[i] = i;
			mu[i] = -1, phi[i] = i - 1;
			ys[i] = 2, d[i] = 1;		
		} 
		for(int j = 1; j <= pcnt && i * prim[j] < maxn; ++j)
        {
        	int k = i * prim[j];
            v[k] = prim[j];
            if(i % prim[j] == 0)
                mu[k] = 0;
                phi[k] = prim[j] * phi[i];
                ys[k] = ys[i] / (d[i] + 1) * (d[i] + 2);
                d[k] = d[i] + 1;
                break;
            }
            else
			{
				mu[k] = -mu[i];
				phi[k] = (prim[j] - 1) * phi[i];
				ys[k] = (ys[i] << 1), d[k] = 1;
			}
        }
	}
}
上一篇:【数论】莫比乌斯反演


下一篇:一个小题,有理数加法