线性筛

数论函数

\(f(n)\) 定义域为 \(N\) (正整数域),值域为 \(N\)
\(f(x)=x\)\(f(x)=x^2\)

积性函数

对于一个函数 \(f(x)\) ,如果 \(\forall a,b,\gcd(a,b)=1,ab=x,f(a)f(b)=f(x)\) ,则称 \(f\) 是积性函数。
证明约数和函数是积性函数:
考虑 \(a,b(\gcd(a,b)=1,ab=x)\)
\(f(a)f(b)=\sum \limits _{d|a}d \sum \limits _{p|b}p= \sum \limits _{d|a}\sum \limits _{p|b}dp\)
因为 \(\gcd(a,b)=1\) ,所以 \(\gcd(d,p)=1\)
所以 \(f(a)f(b)=\sum \limits _{d|a}d \sum \limits _{p|b}p=\sum \limits _{d|a}\sum \limits _{p|b}dp=\sum \limits _{(dp)|(ab)}dp\)
因为 \(ab=x\) ,令 \(t=dp\)
\(f(a)f(b)=\sum \limits _{t|x}t=f(x)\)

埃氏筛

for(int i=2;i<=n;i++)
	if(p[i]) for(int j=2;i*j<=n;j++) p[i*j]=false;

线性筛

每个数被它的最小质因子筛掉。

bool co[N]={false,true};//coprime
int pn[N],cnt;//prime number
for(int i=2;i<=n;i++)
{
	if(!co[i]) pn[++cnt]=i;
	for(int j=1;j<=cnt;j++)
	{
                //pn[j]是i*pn[j]的最小质因子
		if(i*pn[j]>n) break;
		co[i*pn[j]]=true;
		if(!(i%pn[j])) break;
                //i=pn[j]*k
                //如果继续枚举,pn[j+1]*i=pn[j+1]*pn[j]*k
                //一定已经被 pn[j] 筛过了。
	}
}

积性函数筛

给出 \(n\) ,求 \(f(1),f(2), \cdots ,f(n)\) 。其中 \(f(x)= \sum \limits _{d|x} d\)

bool co[N]={false,true};//coprime
int pn[N],f[N]={0,1},cnt;//prime number
int z[N];//z[i]表示p^c。其中p是i的最小质因子。p^c|i,p^{c+1} not|i
for(int i=2;i<=n;i++)
{
	if(!co[i])
	{
		pn[++cnt]=i;
		f[i]=i+1,z[i]=i;
	}
	for(int j=1;j<=cnt;j++)
	{
		//pn[j]是i*pn[j]的最小质因子 
		if(i*pn[j]>n) break;
		co[i*pn[j]]=true;
		if(!(i%pn[j]))
		{
			int x=i*pn[j];
			z[x]=z[i]*pn[j];
			if(z[x]==x) f[x]=f[i]+x;
			//x是pn[j]的幂。
			//f[x]=1+pn[j]+pn[j]^2+...+pn[j]^k
			//i=x/pn[j]
			//f[i]=1+pn[j]+pn[j]^2+...+pn[j]^{k-1}
			//f[x]=f[i]+pn[j]^k=f[i]+x 
			else f[x]=f[x/z[x]]*f[z[x]];
			//i/pn[j]/pn[j]...
			//f[i*pn[j]]=f[i]*f[pn[j]^k]
			
			//pn[j]是i的最小质因子。
			//如果继续枚举,pn[j]就不是i*pn[j]的最小质因子了。
			break;
		}
		else
		{
			f[i*pn[j]]=f[i]*f[pn[j]];
			z[i*pn[j]]=pn[j];
			//i%pn[j]!=0->gcd(i,pn[j])==1
			//pn[j]是i*pn[j]唯一的最小质因子。
		}
	}
}

三个要点:
1.质数的情况
2.\(i \perp p_j\) 的情况(\(a \perp b \Leftrightarrow \gcd(a,b)=1\)
3.\(p_j\)\(i\) 的最小质因子的情况

欧拉函数

\(\varphi(n)\) 表示 \(1\)\(n\) 中与 \(n\) 互质的数的个数。
\(\varphi(n)=\sum \limits _{i=1}^n [i \perp n]\)
\(\varphi(n)\) :
根据整数唯一分解定理,设 \(n=\prod \limits _{i=1}^k p_i^{c_i}\) ( \(p_i\) 是质数),
\(\varphi(n)=n \prod \limits _{i=1}^k \left (1- \frac{1}{p_i} \right )\)

莫比乌斯函数

\(\mu(n)= \begin{cases} 1&n=1\\ (-1)^k&c_i=1\\ 0& \text{otherwise} \end{cases}\)
证明 \(\mu\) 是积性函数:
对于 \(\forall a,b,a \perp b,ab=x\) , 考虑 \(\mu(a)\mu(b)\) :
1.若 \(\mu(a)=0\)\(\mu(b)=0\) ,则 \(ab\) 必含平方因子,则 \(\mu(ab)=\mu(a)\mu(b)=0\)
2.否则,由于 \(a \perp b\) ,则 \(ab\) 也不含平方因子,则 \(\mu(a)\mu(b)=(-1)^{k_1}(-1)^{k_2}=(-1)^{k_1+k_2}=\mu(ab)\)

一般线性筛

对于一个积性函数 \(f\) ,考虑以下的线性筛法:
要计算 \(f(n)\) ,考虑到 \(n=\prod \limits _{i=1}^k p_i^{c_i}\)
在线性筛的过程中,如果 \(i \bmod p_j \neq 0\) ,就有 \(f(i \cdot p_j)=f(i)f(p_j)\)
否则,考虑 \(k|(i \cdot p_j)\)\(k \perp p_j\) ,则有 \(f(i \cdot p_j)=f(k)f( \frac{i \cdot p_j}{k})\)
因此,我们只需要记录对于每一个 \(i \cdot p_j\) 对应的 \(k\) ,和推导出从 \(f(p^c)\)\(f(p^{c+1})\) 的关系式即可。

一个例题

\(f(i)\) 表示有序三元组 \((a,b,c)\) 的个数,使得 \(abc=i\) 。求出 \(f(1)\) ~ \(f(n)\)\(n \leq 10^7\)
证明 \(f\) 是积性函数
写出式子: \(f(i)=\sum \limits_{a|i} \sum \limits_{b|i} \sum \limits_{c|i} [abc=i]\)
显然,原式等于 \(\sum \limits_{a|i} \sum \limits_{b| \frac{i}{a}} 1\)
\(d(n)\) 表示 \(n\) 的约数个数,
则原式可转化为 \(\sum \limits_{a|i} d(\frac{i}{a})\)
\(\sum \limits_{a|i} d(a)\)
所以,要先证明 \(d\) 是积性函数。
\(d(a)d(b)=\sum \limits_{x|a} 1 \sum \limits_{y|b} 1\)
因为 \(a \perp b\) ,所以 \(x \perp y\)
所以原式等于 \(\sum \limits_{(xy)|(ab)} 1\)
所以 \(d(a)d(b)=d(ab)\)
所以 \(d\) 是积性函数。
所以 \(f(a)f(b)=\sum \limits_{x|a} d(x) \sum \limits_{y|b} d(y)\)
因为 \(a \perp b\) ,所以 \(x \perp y\)
所以原式等于 \(\sum \limits_{(xy)|(ab)} d(x)d(y)\)
因为 \(d\) 是积性函数,
所以原式等于 \(\sum \limits_{(xy)|(ab)} d(xy)\)
所以 \(f(a)f(b)=f(ab)\)
所以 \(f\) 是积性函数。
所以就可以开始筛了。

考虑 \(f(p^k)\)
\(a=p^x\)\(b=p^y\)\(c=p^z\)
那么 \(k=x+y+z\)
用插板法可求出方案为 \(C(k+2,2)\)
筛的时候记一下 \(k\) 即可。

posted @ 2020-04-13 22:13  BBD186587  阅读(253)  评论(1编辑  收藏  举报