其实主要是想发一下线性筛的板子,包括线性筛质数,约数个数,欧拉函数和莫比乌斯函数。
有些也会有一点简单的证明。
线性筛质数就不说啦。
然后加一个筛欧拉函数。
当(i)为质数的时候,自然(varphi(i) = i - 1)。
令(n = mp),
当(p
mid m)的时候,有(varphi(n) = varphi(m) * varphi(p) = varphi(m) * (p - 1))。
否则有(varphi(n) = varphi(m) * p)。
证明一下吧:
首先(p
mid m)时,根据积性,(varphi(n) = varphi(m) * (p - 1))。
考虑另一种情况,
若(p mid m),令(m = k * p ^ x),这样保证了(k, p)互质。
所以
然后看等式右边:
(也不知道这算不算证明)
另一种证明(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]
mid 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;
}
}
}
}