约数定义
约数:约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数
1.求n的约数
vector<ll> get_divisors(ll n){//试除法求n的所有约数
vector<ll> ans;
for (ll i = 1; i <= n / i; i++) {
if (n % i == 0) {
ans.push_back(i);
if (i != n / i) ans.push_back(n / i);
}
}
//sort(ans.begin(), ans.end());
return ans;
}
2.求n的约数个数
用
d
i
d_i
di 表示
i
i
i 的约数个数,
n
u
m
i
num_i
numi 表示
i
i
i 的最小质因子出现次数。
定理:若
n
=
∏
i
=
1
m
p
i
c
i
n=\prod_{i=1}^mp_i^{c_i}
n=∏i=1mpici 则
d
i
=
∏
i
=
1
m
c
i
+
1
d_i=\prod_{i=1}^mc_i+1
di=∏i=1mci+1.
证明:我们知道
p
i
c
i
p_i^{c_i}
pici 的约数有
p
i
0
,
p
i
1
,
…
,
p
i
c
i
p_i^0,p_i^1,\dots ,p_i^{c_i}
pi0,pi1,…,pici 共
c
i
+
1
c_i+1
ci+1 个,根据乘法原理,
n
n
n 的约数个数就是
∏
i
=
1
m
c
i
+
1
\prod_{i=1}^mc_i+1
∏i=1mci+1.
代码一:线性筛
void pre() {
d[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!v[i]) v[i] = 1, p[++tot] = i, d[i] = 2, num[i] = 1;
for (int j = 1; j <= tot && i <= n / p[j]; ++j) {
v[p[j] * i] = 1;
if (i % p[j] == 0) {
num[i * p[j]] = num[i] + 1;
d[i * p[j]] = d[i] / num[i * p[j]] * (num[i * p[j]] + 1);
break;
} else {
num[i * p[j]] = 1;
d[i * p[j]] = d[i] * 2;
}
}
}
}
代码二:
ll getnum(ll n){ //计算n的约数个数
ll ans = 1;
for (ll i = 2; i <= n / i; i++) {
ll k = 0;
while (n % i == 0) {
n = n / i;
k++;
}
if (k) ans *= (k + 1);
}
if (n != 1) ans = ans * 2;
if (ans == 1) {
if (n == 1) return 1;
else return 2;
}
return ans;
}
3.求n的约数之和
f
i
f_i
fi 表示
i
i
i 的约数和,
g
i
g_i
gi 表示
i
i
i 的最小质因子的
p
+
p
1
+
p
2
+
…
p
k
p+p^1+p^2+\dots p^k
p+p1+p2+…pk.
代码一:线性筛
void pre() {
g[1] = f[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!v[i]) v[i] = 1, p[++tot] = i, g[i] = i + 1, f[i] = i + 1;
for (int j = 1; j <= tot && i <= n / p[j]; ++j) {
v[p[j] * i] = 1;
if (i % p[j] == 0) {
g[i * p[j]] = g[i] * p[j] + 1;
f[i * p[j]] = f[i] / g[i] * g[i * p[j]];
break;
} else {
f[i * p[j]] = f[i] * f[p[j]];
g[i * p[j]] = 1 + p[j];
}
}
}
for (int i = 1; i <= n; ++i) f[i] = (f[i - 1] + f[i]) % Mod;
}
代码二:
ll qpow(ll a, ll b) {
ll ans = 1;
while (b) {
if (b & 1)ans *= a;
a *= a;
b >>= 1;
}
return ans;
}
ll getsum(ll n) {//计算n的约数和是多少.
ll ans = 1;
for (ll i = 2; i <= n / i; i++) {
ll t = 0;
while (n % i == 0) {
n = n / i;
t++;
}
ans *= ((1 - qpow(i, t + 1)) / (1 - i));
}
if (n != 1) ans *= (1 + n);
return ans;
}