Skip to content

Commit ec9505b

Browse files
committed
Sum of Totien Function
1 parent 9582940 commit ec9505b

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

cp-algo/number_theory/dirichlet.hpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ namespace cp_algo::math {
1010
return std::pair{rt_n, 2 * rt_n - (n / rt_n == rt_n)};
1111
}
1212

13+
auto floor_generator(int64_t n) {
14+
auto [rt_n, num_floors] = floor_stats(n);
15+
return [n, rt_n = rt_n, num_floors = num_floors](int k) {
16+
return k <= rt_n ? int64_t(k) : n / int64_t(num_floors - k + 1);
17+
};
18+
}
19+
20+
auto floors(int64_t n) {
21+
auto [_, m] = floor_stats(n);
22+
return std::views::iota(0, m+1) | std::views::transform(floor_generator(n));
23+
}
24+
1325
struct interval {
1426
int lo, hi;
1527
auto operator <=>(const interval&) const = default;
@@ -96,8 +108,8 @@ namespace cp_algo::math {
96108
}
97109

98110
auto Dirichlet_div(auto const& H, auto const& G, int64_t n) {
99-
auto m = size(G);
100-
auto F = H | std::views::take(m) | std::ranges::to<std::decay_t<decltype(G)>>();
111+
auto m = std::size(G);
112+
auto F = H | std::views::take(m) | std::ranges::to<std::vector>();
101113
Dirichlet_div_inplace(F, G, n);
102114
return F;
103115
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// @brief Sum of Totient Function
2+
#define PROBLEM "https://judge.yosupo.jp/problem/sum_of_totient_function"
3+
#pragma GCC optimize("Ofast,unroll-loops")
4+
#include <iostream>
5+
#include "blazingio/blazingio.min.hpp"
6+
#include "cp-algo/number_theory/modint.hpp"
7+
#include "cp-algo/number_theory/dirichlet.hpp"
8+
#include "cp-algo/util/big_alloc.hpp"
9+
#include <bits/stdc++.h>
10+
11+
using namespace std;
12+
using namespace cp_algo::math;
13+
using base = modint<998244353>;
14+
15+
void solve() {
16+
int64_t n;
17+
cin >> n;
18+
auto H = floors(n) | views::transform([](int64_t k) {
19+
return base(k) * base(k + 1) / 2;
20+
}) | ranges::to<vector>();
21+
auto G = floors(n) | views::transform([](int64_t k) {
22+
return base(k);
23+
}) | ranges::to<vector>();
24+
auto F = Dirichlet_div(H, G, n);
25+
cout << F.back() << "\n";
26+
}
27+
28+
signed main() {
29+
//freopen("input.txt", "r", stdin);
30+
ios::sync_with_stdio(0);
31+
cin.tie(0);
32+
int t = 1;
33+
//cin >> t;
34+
while(t--) {
35+
solve();
36+
}
37+
}

0 commit comments

Comments
 (0)