线性筛——约数的个数

如果不会线性筛素数的话,建议先看这篇博客了解一下线性筛素数。
线性寻找约数的个数(积性函数都可以线性筛)主要是在线性筛素数的基础上得到的

f ( n ) f(n) f(n) 表示 n n n 的约数的个数
g ( n ) g(n) g(n) 表示 n n n 的最小质因子的个数

我们知道:
n = ∏ i = 1 n p i t i n=\prod_{i=1}^n p_i^{t_i} n=i=1npiti

f ( n ) = ∑ i = 1 n ( t i + 1 ) f(n)=\sum_{i=1}^n(t_i+1) f(n)=i=1n(ti+1)

所以:
1、当 n n n 是质数时, g ( n ) = 1 , f ( n ) = 2 g(n)=1\quad , \quad f(n)=2 g(n)=1,f(n)=2
对于 2和3 设 d = n p d=\frac{n}{p} d=pn 其中 p p p n n n 的最小质因子
2、当 p p p d d d 的某个质因子时, 则 g ( n ) = g ( d ) + 1 , f ( n ) = f ( d ) ∗ ( g ( n ) + 1 ) g ( d ) + 1 g(n)=g(d)+1\quad, \quad f(n)=\frac{f(d)*(g(n)+1)}{g(d)+1} g(n)=g(d)+1,f(n)=g(d)+1f(d)(g(n)+1)
3、当 p p p d d d 互质时, g ( n ) = 1 , f ( n ) = f ( d ) ∗ ( g ( n ) + 1 ) g(n)=1\quad,\quad f(n)=f(d)*(g(n)+1) g(n)=1,f(n)=f(d)(g(n)+1)

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

int num[MAXN],d[MAXN];//num存约数个数,d存一个数最小质因子的个数
void fun(int n)
{
	memset(vis,0,sizeof(vis));
	num[1]=1;
	d[1]=1;
	prime[0]=0;
	for(int i=2;i<=n;i++)
	{
		if(!vis[i])
		{
			prime[++prime[0]]=i;
			d[i]=1;
			num[i]=2;
		}
		for(int j=1;j<=prime[0]&&i<=n/prime[j];j++)
		{
			vis[i*prime[j]]=1;
			if(i%prime[j]==0)
			{
				d[i*prime[j]]=d[i]+1;
				num[i*prime[j]]=num[i]/(d[i]+1)*(d[i]+2);
				break;
			}
			d[i*prime[j]]=1;
			num[i*prime[j]]=num[i]*2;
		}
	}
}

你可能感兴趣的:(数论)