除数函数d(n)与约数和

除数函数 d ( n ) d(n) d(n)

定义:除数函数 d ( n ) d(n) d(n) 是一个算术函数,用于计算正整数 n n n 的正约数个数。

例如 d ( 6 ) = 4 d(6) = 4 d(6)=4, 因为 1 , 2 , 3 , 6 1, 2, 3, 6 1,2,3,6 都是它的约数。


公式

n = p 1 a 1 ∗ p 2 a 2 ∗ . . . ∗ p k a k n = p_1 ^ {a_1}*p_2 ^ {a_2}*...*p_k ^ {a_k} n=p1a1p2a2...pkak, 其中 p i p_i pi 为质数,则 d ( n ) = ( a 1 + 1 ) ∗ ( a 2 + 1 ) ∗ . . . ∗ ( a k + 1 ) d(n)=(a_1+1)*(a_2+1)*...*(a_k+1) d(n)=(a1+1)(a2+1)...(ak+1)

这一点很好理解,将 n n n 分解质因数后,每个质因子都有 a i + 1 a_i + 1 ai+1 种取法(可以不取,即 0 0 0 个),做一个乘法原理,即为 n n n 的约数个数


求解 d(n)

一、求解单个值

n = a ∗ b , a < = b n=a*b, a <= b n=ab,a<=b, 则有 a ≤ n a \leq \sqrt{n} an , 所以我们只需要枚举 n \sqrt{n} n 内的约数 a a a, 大于 n \sqrt{n} n 的约数可以通过 n a \frac{n}{a} an 得到。注意一下,当 a = b = n a=b=\sqrt{n} a=b=n 时,别重复计数。时间复杂度 O ( n ) O(\sqrt{n}) O(n )

int dn = 0;
for (int i = 1; i*i <= n; i++) {
	if (n % i == 0) {
		dn += 2;
		if (i * i == n) dn--;
	}
}

二、求解 d ( 1 ) ∼ d ( n ) d(1) \sim d(n) d(1)d(n)

可以使用线性筛求解, 时间复杂度 O ( n ) O(n) O(n)

// 用 d[i] 表示 i 的约数个数,num[i] 表示 i 的最小质因子出现次数
void calc_dn()
{
	d[1] = 1;
	for (int i = 2; i < N; i++) {
		if (!flag[i]) flag[i] = 1, prime[++lp] = i, d[i] = 2, num[i] = 1;
		for (int j = 1; j <= lp && i * prime[j] < N; j++) {
			flag[prime[j] * i] = 1;
			if (i % prime[j] == 0) {
				num[i * prime[j]] = num[i] + 1;
				d[i * prime[j]] = d[i] / num[i * prime[j]] * (num[i * prime[j]] + 1);
				break;
			}
			else {
				num[i * prime[j]] = 1;
				d[i * prime[j]] = d[i] * 2;
			}
		}
	}
}

除数函数的上界

参考论文

感兴趣可以自己看上述论文,这里给出结论:

log ⁡ d ( n ) < 1.066 log ⁡ n log ⁡ log ⁡ n , n ≥ 3 \log{d(n)} < 1.066\frac{\log{n}}{\log{\log{n}}}, n \geq 3 logd(n)<1.066loglognlogn,n3

大多数人关心的应该是具体的数值,下边给出:

1 0 9 10^9 109 以内, d ( n ) ≤ 1344 d(n) \leq 1344 d(n)1344

2 31 − 1 2^{31}-1 2311 以内, d ( n ) ≤ 1600 d(n) \leq 1600 d(n)1600

1 0 18 10^{18} 1018 以内, d ( n ) ≤ 103680 d(n) \leq 103680 d(n)103680

2 63 − 1 2^{63}-1 2631 以内, d ( n ) ≤ 161280 d(n) \leq 161280 d(n)161280

参考:除数函数的渐近上界?

约数和

咕咕咕

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值