-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmax_prime_dp.cpp
45 lines (42 loc) · 1.01 KB
/
max_prime_dp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
vector<int> max_prime_dp(const int max_x=1e6) {
vector<int> dp(max_x+1);
dp[1] = 1;
for (int i = 2; i <= max_x; i++) {
if (dp[i]) continue;
for (int j = i; j <= max_x; j+=i)
dp[j] = i;
}
return dp;
}
void prime_factor_iter(int x, const vector<int> &max_prime, auto f) {
assert(x < (int)max_prime.size());
// void f(prime, cnt)
static_assert(std::is_invocable_r_v<void, decltype(f), int, int>);
int prev = max_prime[x], cnt = 1;
do {
x /= prev;
int p = max_prime[x];
if (p == prev) {
++cnt;
} else {
f(prev, cnt);
cnt = 1;
prev = p;
}
} while (x > 1);
}
ll cnt_divisors(int x, const vector<int> &max_prime) {
ll res = 1;
prime_factor_iter(x, max_prime, [&res](int, int cnt) {
res *= cnt + 1;
});
return res;
}
ll sum_divisors(int x, const vector<int> &max_prime) {
ll res = 1;
prime_factor_iter(x, max_prime, [&res](int p, int cnt) {
// sum(p**i for i in range(cnt+1))
res *= (fpow(p, cnt + 1) - 1) / (p - 1);
});
return res;
}