线性筛——对i从1取到n gcd(i,n)求和

走远了吗. 提交于 2019-12-02 11:46:48

如果不会线性筛素数的话,建议先看这篇博客了解一下线性筛素数。

f(n)=i=1ngcd(i,n)f(n)=\sum_{i=1}^{n}\gcd(i,n)

容易证明f(n)f(n)一定是积性函数

f(p1t1p2t2pktk)=f(p1t1)f(p2t2)f(pktk)f(p_1^{t_1} p_2^{t_2}\cdots p_k^{t_k}) =f(p_1^{t_1} )f(p_2^{t_2} ) \cdots f(p_k^{t_k} )

又因为

f(n)=i=1ngcd(i,n)=dndin[gcd(i,n)=d]=dndϕ(nd) \begin{aligned} f(n)&=\sum_{i=1}^{n} \gcd(i,n)\\ &=\sum_{d|n} d* \sum_i^n [\gcd(i,n)=d]\\ &= \sum_{d|n} d *\phi( \frac{n}{d} )\\ \end{aligned}
于是
f(pt)=i=1ptgcd(i,pt)=(i=0t1piϕ(pti))+pt=(i=0t1pi(pti1)(p1))+pt=(i=0t1ptpt1))+pt=(t+1)pttpt1 \begin{aligned} f(p^t) &=\sum_{i=1}^{p^t} \gcd(i,p^t)\\ &= \left( \sum_{i=0}^{t-1} p^i*\phi(p^{t-i}) \right) + p^t\\ &=\left( \sum_{i=0}^{t-1} p^i*(p^{t-i-1})*(p-1) \right) + p^t\\ &=\left( \sum_{i=0}^{t-1} p^{t}-p^{t-1}) \right) + p^t\\ &=(t+1)*p^t-t*p^{t-1} \end{aligned}

所以:
g(n)g(n)为n的所有质因子中所有最小质因子的乘积
t(n)t(n)为n的所有质因子中所有最小质因子的数目

1、当 nn 是质数时,g(n)=n,f(n)=2n1,t(n)=1g(n)=n\quad , \quad f(n)=2*n-1\quad , \quad t(n)=1
对于 2和3 设 d=npd=\frac{n}{p} 其中 ppnn 的最小质因子
2、当 ppdd 的某个质因子时, 则 g(n)=g(d)p,f(n)=f(d)((t(n)+1)g(n)(t(d)+1)g(d))f(g(d)),t(n)=t(d)+1g(n)=g(d)*p\quad, \quad f(n)=\frac{f(d)*((t(n)+1)*g(n)-(t(d)+1)*g(d))}{f(g(d))}\quad, \quad t(n)=t(d)+1
3、当 ppdd 互质时,g(n)=n,f(n)=f(d)f(p),t(n)=1g(n)=n\quad,\quad f(n)=f(d)*f(p)\quad,\quad t(n)=1

good luck and have fun!!!
附上代码:

int f[MAXN],prime[MAXN],d[MAXN],dd[MAXN];
\\dd表示g函数
\\d表示t函数
void get_it(int n)
{
	memset(prime,0,sizeof prime);
	f[1]=mu[1]=1;
	for(int i=2;i<=n;i++){
		if(!prime[i]){
			prime[++prime[0]]=i;
			dd[i]=i;
			d[i]=1;
			f[i]=2*i-1;
		}
		for(int j=1;j<=prime[0]&&prime[j]<=n/i;j++){
			prime[i*prime[j]]=1;
			if(i%prime[j]==0){
				d[i*prime[j]]=d[i]+1;
				dd[i*prime[j]]=dd[i]*prime[j];
				f[i*prime[j]]=f[i]/f[dd[i]]*(1ll*(d[i]+2)*dd[i*prime[j]]-1ll*d[i*prime[j]]*dd[i]);
				break;
			}
			d[i*prime[j]]=1;
			dd[i*prime[j]]=prime[j];
			f[i*prime[j]]=f[i]*(2*prime[j]-1);
		}
	}
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!