From 1cab297ce5eda2fc44b36fe13012976640785ab4 Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 06:35:14 +0000 Subject: [PATCH 01/16] Migrate 20 headers to self-contained includes --- SELF_CONTAINED_HEADER_MIGRATION.md | 55 +++++++------ dp/cumulative-sum-2d.hpp | 8 +- dp/cumulative-sum.hpp | 12 ++- dp/edit-distance.hpp | 16 ++-- dp/knapsack-01-2.hpp | 15 +++- dp/knapsack-01.hpp | 14 +++- dp/knapsack-limitations.hpp | 19 +++-- dp/knapsack.hpp | 14 +++- dp/largest-rectangle.hpp | 18 +++-- dp/longest-increasing-subsequence.hpp | 19 +++-- dp/monotone-minima.hpp | 22 ++++-- scripts/self-contained-headers.txt | 20 +++++ structure/class/act.hpp | 3 + structure/class/acted-monoid.hpp | 3 + structure/class/affine.hpp | 3 + structure/class/beats-monoid.hpp | 3 + structure/class/range-add-range-min.hpp | 7 +- .../class/range-chmin-chmax-add-range-sum.hpp | 27 +++++-- structure/others/slope-trick.hpp | 35 +++++--- structure/others/sqrt-decomposition.hpp | 54 ++++++++----- structure/others/union-rectangle.hpp | 14 +++- .../self-contained-header-migration.test.cpp | 79 +++++++++++++++++++ 22 files changed, 340 insertions(+), 120 deletions(-) create mode 100644 test/unittest/self-contained-header-migration.test.cpp diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index b5cf91f66..0fdac5f70 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -22,7 +22,7 @@ | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 20 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 40 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -94,32 +94,35 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null ## 移行履歴 -| 日付 | 対象 | 備考 | -| ---------- | ---------------------------------------------------------- | ---------------------------- | -| 2026-08-04 | `structure/others/sparse-table.hpp` | 標準 include と `std::` 修飾 | -| 2026-08-04 | `structure/others/disjoint-sparse-table.hpp` | 標準 include と `std::` 修飾 | -| 2026-08-04 | `structure/others/plus-minus-one-rmq.hpp` | Sparse Table 依存を明示 | -| 2026-08-04 | `structure/others/queue-operate-aggregation.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/deque-operate-aggregation.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/abstract-binary-indexed-tree.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/binary-indexed-tree.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/persistent-array.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/priority-sum-structure.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/linear-rmq.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/union-find.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/weighted-union-find.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/union-find-undo.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/partially-persistent-union-find.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/persistent-union-find.hpp` | Persistent Array 依存を明示 | -| 2026-08-04 | `structure/union-find/bipartite-graph.hpp` | Union Find 依存を明示 | -| 2026-08-04 | `structure/heap/erasable-heap.hpp` | 標準依存を補完 | -| 2026-08-04 | `structure/heap/leftist-heap.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/heap/persistent-leftist-heap.hpp` | Leftist Heap 依存を明示 | -| 2026-08-04 | `structure/heap/skew-heap.hpp` | 標準依存を明示 | +| 日付 | 対象 | 備考 | +| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | +| 2026-08-04 | `structure/others/sparse-table.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-04 | `structure/others/disjoint-sparse-table.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-04 | `structure/others/plus-minus-one-rmq.hpp` | Sparse Table 依存を明示 | +| 2026-08-04 | `structure/others/queue-operate-aggregation.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/deque-operate-aggregation.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/abstract-binary-indexed-tree.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/binary-indexed-tree.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/persistent-array.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/priority-sum-structure.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/linear-rmq.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/union-find.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/weighted-union-find.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/union-find-undo.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/partially-persistent-union-find.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/persistent-union-find.hpp` | Persistent Array 依存を明示 | +| 2026-08-04 | `structure/union-find/bipartite-graph.hpp` | Union Find 依存を明示 | +| 2026-08-04 | `structure/heap/erasable-heap.hpp` | 標準依存を補完 | +| 2026-08-04 | `structure/heap/leftist-heap.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/heap/persistent-leftist-heap.hpp` | Leftist Heap 依存を明示 | +| 2026-08-04 | `structure/heap/skew-heap.hpp` | 標準依存を明示 | +| 2026-08-10 | `dp/cumulative-sum-2d.hpp`、`dp/cumulative-sum.hpp`、`dp/edit-distance.hpp`、`dp/knapsack-01-2.hpp`、`dp/knapsack-01.hpp`、`dp/knapsack-limitations.hpp`、`dp/knapsack.hpp`、`dp/largest-rectangle.hpp`、`dp/longest-increasing-subsequence.hpp`、`dp/monotone-minima.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `structure/class/act.hpp`、`structure/class/acted-monoid.hpp`、`structure/class/affine.hpp`、`structure/class/beats-monoid.hpp`、`structure/class/monoid.hpp`、`structure/class/range-add-range-min.hpp`、`structure/class/range-chmin-chmax-add-range-sum.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `structure/others/slope-trick.hpp`、`structure/others/sqrt-decomposition.hpp`、`structure/others/union-rectangle.hpp` | 標準 include と `std::` 修飾 | ## 次の候補 次の候補として、プロジェクト内ヘッダーへの依存がない -`structure/others/slope-trick.hpp` と -`structure/others/generalized-slope-trick.hpp` を検討する。その後も依存関係の葉に -近いヘッダーから進め、1コミットの変更範囲を小さく保つ。 +`structure/others/generalized-slope-trick.hpp` と、標準依存を補完しやすい +`structure/others/permutation-tree.hpp` を検討する。その後も依存関係の葉に近い +ヘッダーから進め、1コミットの変更範囲を小さく保つ。 diff --git a/dp/cumulative-sum-2d.hpp b/dp/cumulative-sum-2d.hpp index 2d50f5c9c..e57e0accd 100644 --- a/dp/cumulative-sum-2d.hpp +++ b/dp/cumulative-sum-2d.hpp @@ -1,8 +1,12 @@ +#pragma once + +#include + template struct CumulativeSum2D { - vector > data; + std::vector > data; - CumulativeSum2D(int W, int H) : data(W + 1, vector(H + 1, 0)) {} + CumulativeSum2D(int W, int H) : data(W + 1, std::vector(H + 1, 0)) {} void add(int x, int y, T z) { ++x, ++y; diff --git a/dp/cumulative-sum.hpp b/dp/cumulative-sum.hpp index 1306c6272..46039e5da 100644 --- a/dp/cumulative-sum.hpp +++ b/dp/cumulative-sum.hpp @@ -1,10 +1,16 @@ +#pragma once + +#include +#include +#include + template struct CumulativeSum { - vector data; + std::vector data; CumulativeSum() = default; - explicit CumulativeSum(size_t sz) : data(sz + 1, 0) {} + explicit CumulativeSum(std::size_t sz) : data(sz + 1, 0) {} void add(int k, const T& x) { data[k + 1] += x; } @@ -16,7 +22,7 @@ struct CumulativeSum { T fold(int r) const { if (r < 0) return 0; - return data[min(r, (int)data.size() - 1)]; + return data[std::min(r, (int)data.size() - 1)]; } T fold(int l, int r) const { return fold(r) - fold(l); } diff --git a/dp/edit-distance.hpp b/dp/edit-distance.hpp index 1e248462e..bf10760a8 100644 --- a/dp/edit-distance.hpp +++ b/dp/edit-distance.hpp @@ -1,13 +1,19 @@ -int edit_distance(const string& S, const string& T) { +#pragma once + +#include +#include +#include + +int edit_distance(const std::string& S, const std::string& T) { const int N = (int)S.size(), M = (int)T.size(); - vector > dp(N + 1, vector(M + 1, N + M)); + std::vector > dp(N + 1, std::vector(M + 1, N + M)); for (int i = 0; i <= N; i++) dp[i][0] = i; for (int i = 0; i <= M; i++) dp[0][i] = i; for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) { - dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1); - dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); - dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + (S[i - 1] != T[j - 1])); + dp[i][j] = std::min(dp[i][j], dp[i - 1][j] + 1); + dp[i][j] = std::min(dp[i][j], dp[i][j - 1] + 1); + dp[i][j] = std::min(dp[i][j], dp[i - 1][j - 1] + (S[i - 1] != T[j - 1])); } } return dp[N][M]; diff --git a/dp/knapsack-01-2.hpp b/dp/knapsack-01-2.hpp index 682ea4759..4909cd4c7 100644 --- a/dp/knapsack-01-2.hpp +++ b/dp/knapsack-01-2.hpp @@ -1,12 +1,19 @@ +#pragma once + +#include +#include +#include + template -T knapsack_01_2(const vector& w, const vector& v, const T& W) { +T knapsack_01_2(const std::vector& w, const std::vector& v, + const T& W) { const int N = (int)w.size(); - const int sum = accumulate(begin(v), end(v), 0); - vector dp(sum + 1, W + 1); + const int sum = std::accumulate(v.begin(), v.end(), 0); + std::vector dp(sum + 1, W + 1); dp[0] = T(); for (int i = 0; i < N; i++) { for (int j = sum; j >= v[i]; j--) { - dp[j] = min(dp[j], dp[j - v[i]] + w[i]); + dp[j] = std::min(dp[j], dp[j - v[i]] + w[i]); } } int ret = 0; diff --git a/dp/knapsack-01.hpp b/dp/knapsack-01.hpp index d633793af..2586ff36e 100644 --- a/dp/knapsack-01.hpp +++ b/dp/knapsack-01.hpp @@ -1,8 +1,14 @@ -template > -vector knapsack_01(const vector& w, const vector& v, const int& W, - const T& NG, const Compare& comp = Compare()) { +#pragma once + +#include +#include + +template > +std::vector knapsack_01(const std::vector& w, const std::vector& v, + const int& W, const T& NG, + const Compare& comp = Compare()) { const int N = (int)w.size(); - vector dp(W + 1, NG); + std::vector dp(W + 1, NG); dp[0] = T(); for (int i = 0; i < N; i++) { for (int j = W; j >= w[i]; j--) { diff --git a/dp/knapsack-limitations.hpp b/dp/knapsack-limitations.hpp index d5298465c..5019f3097 100644 --- a/dp/knapsack-limitations.hpp +++ b/dp/knapsack-limitations.hpp @@ -1,11 +1,18 @@ -template > -vector knapsack_limitations(const vector& w, const vector& m, - const vector& v, const int& W, const T& NG, - const Compare& comp = Compare()) { +#pragma once + +#include +#include + +template > +std::vector knapsack_limitations(const std::vector& w, + const std::vector& m, + const std::vector& v, const int& W, + const T& NG, + const Compare& comp = Compare()) { const int N = (int)w.size(); - vector dp(W + 1, NG), deqv(W + 1); + std::vector dp(W + 1, NG), deqv(W + 1); dp[0] = T(); - vector deq(W + 1); + std::vector deq(W + 1); for (int i = 0; i < N; i++) { if (w[i] == 0) { for (int j = 0; j <= W; j++) { diff --git a/dp/knapsack.hpp b/dp/knapsack.hpp index 2092b7b7c..1a1bf7272 100644 --- a/dp/knapsack.hpp +++ b/dp/knapsack.hpp @@ -1,8 +1,14 @@ -template > -vector knapsack(const vector& w, const vector& v, const int& W, - const T& NG, const Compare& comp = Compare()) { +#pragma once + +#include +#include + +template > +std::vector knapsack(const std::vector& w, const std::vector& v, + const int& W, const T& NG, + const Compare& comp = Compare()) { const int N = (int)w.size(); - vector dp(W + 1, NG); + std::vector dp(W + 1, NG); dp[0] = T(); for (int i = 0; i < N; i++) { for (int j = w[i]; j <= W; j++) { diff --git a/dp/largest-rectangle.hpp b/dp/largest-rectangle.hpp index 16921dd50..619f3277c 100644 --- a/dp/largest-rectangle.hpp +++ b/dp/largest-rectangle.hpp @@ -1,12 +1,20 @@ +#pragma once + +#include +#include +#include +#include + template -int64_t largest_rectangle(vector height) { - stack st; +std::int64_t largest_rectangle(std::vector height) { + std::stack st; height.push_back(0); - vector left(height.size()); - int64_t ret = 0; + std::vector left(height.size()); + std::int64_t ret = 0; for (int i = 0; i < height.size(); i++) { while (!st.empty() && height[st.top()] >= height[i]) { - ret = max(ret, (int64_t)(i - left[st.top()] - 1) * height[st.top()]); + ret = std::max(ret, + (std::int64_t)(i - left[st.top()] - 1) * height[st.top()]); st.pop(); } left[i] = st.empty() ? -1 : st.top(); diff --git a/dp/longest-increasing-subsequence.hpp b/dp/longest-increasing-subsequence.hpp index 631e5b4be..1654983fe 100644 --- a/dp/longest-increasing-subsequence.hpp +++ b/dp/longest-increasing-subsequence.hpp @@ -1,13 +1,20 @@ +#pragma once + +#include +#include +#include + template -size_t longest_increasing_subsequence(const vector& a, bool strict) { - vector lis; +std::size_t longest_increasing_subsequence(const std::vector& a, + bool strict) { + std::vector lis; for (auto& p : a) { - typename vector::iterator it; + typename std::vector::iterator it; if (strict) - it = lower_bound(begin(lis), end(lis), p); + it = std::lower_bound(lis.begin(), lis.end(), p); else - it = upper_bound(begin(lis), end(lis), p); - if (end(lis) == it) + it = std::upper_bound(lis.begin(), lis.end(), p); + if (lis.end() == it) lis.emplace_back(p); else *it = p; diff --git a/dp/monotone-minima.hpp b/dp/monotone-minima.hpp index 894a79f0f..71a73ba50 100644 --- a/dp/monotone-minima.hpp +++ b/dp/monotone-minima.hpp @@ -1,10 +1,16 @@ -template > -vector > monotone_minima(int H, int W, - const function& f, - const Compare& comp = Compare()) { - vector > dp(H); - function dfs = [&](int top, int bottom, int left, - int right) { +#pragma once + +#include +#include +#include + +template > +std::vector > monotone_minima( + int H, int W, const std::function& f, + const Compare& comp = Compare()) { + std::vector > dp(H); + std::function dfs = [&](int top, int bottom, + int left, int right) { if (top > bottom) return; int line = (top + bottom) / 2; T ma; @@ -16,7 +22,7 @@ vector > monotone_minima(int H, int W, mi = i; } } - dp[line] = make_pair(mi, ma); + dp[line] = std::make_pair(mi, ma); dfs(top, line - 1, left, mi); dfs(line + 1, bottom, mi, right); }; diff --git a/scripts/self-contained-headers.txt b/scripts/self-contained-headers.txt index e5fba2723..c6467dc88 100644 --- a/scripts/self-contained-headers.txt +++ b/scripts/self-contained-headers.txt @@ -1,4 +1,21 @@ # Headers migrated to direct includes and explicit std:: qualification. +dp/cumulative-sum-2d.hpp +dp/cumulative-sum.hpp +dp/edit-distance.hpp +dp/knapsack-01-2.hpp +dp/knapsack-01.hpp +dp/knapsack-limitations.hpp +dp/knapsack.hpp +dp/largest-rectangle.hpp +dp/longest-increasing-subsequence.hpp +dp/monotone-minima.hpp +structure/class/act.hpp +structure/class/acted-monoid.hpp +structure/class/affine.hpp +structure/class/beats-monoid.hpp +structure/class/monoid.hpp +structure/class/range-add-range-min.hpp +structure/class/range-chmin-chmax-add-range-sum.hpp structure/heap/erasable-heap.hpp structure/heap/leftist-heap.hpp structure/heap/persistent-leftist-heap.hpp @@ -12,7 +29,10 @@ structure/others/persistent-array.hpp structure/others/plus-minus-one-rmq.hpp structure/others/priority-sum-structure.hpp structure/others/queue-operate-aggregation.hpp +structure/others/slope-trick.hpp structure/others/sparse-table.hpp +structure/others/sqrt-decomposition.hpp +structure/others/union-rectangle.hpp structure/union-find/bipartite-graph.hpp structure/union-find/partially-persistent-union-find.hpp structure/union-find/persistent-union-find.hpp diff --git a/structure/class/act.hpp b/structure/class/act.hpp index 168f4f756..0993b8742 100644 --- a/structure/class/act.hpp +++ b/structure/class/act.hpp @@ -1,5 +1,7 @@ #pragma once +#pragma once + template struct LambdaAct { using F = F2; @@ -27,3 +29,4 @@ struct Act { static constexpr F id() const {} }; */ +#pragma once diff --git a/structure/class/acted-monoid.hpp b/structure/class/acted-monoid.hpp index 6d439022a..c125163ac 100644 --- a/structure/class/acted-monoid.hpp +++ b/structure/class/acted-monoid.hpp @@ -1,5 +1,7 @@ #pragma once +#pragma once + template struct LambdaActedMonoid { @@ -54,3 +56,4 @@ struct ActedMonoid { static constexpr F id() {} }; */ +#pragma once diff --git a/structure/class/affine.hpp b/structure/class/affine.hpp index faf34956d..5d18c680d 100644 --- a/structure/class/affine.hpp +++ b/structure/class/affine.hpp @@ -1,3 +1,5 @@ +#pragma once + template struct Affine { T a, b; // ax+b @@ -14,3 +16,4 @@ struct Affine { return a != p.a or b != p.b; } }; +#pragma once diff --git a/structure/class/beats-monoid.hpp b/structure/class/beats-monoid.hpp index b67517e18..6dd87730c 100644 --- a/structure/class/beats-monoid.hpp +++ b/structure/class/beats-monoid.hpp @@ -1,5 +1,7 @@ #pragma once +#pragma once + template struct LambdaBeatsMonoid { @@ -55,3 +57,4 @@ struct BeatsMonoid { static constexpr F id() {} }; */ +#pragma once diff --git a/structure/class/range-add-range-min.hpp b/structure/class/range-add-range-min.hpp index 7ed977b38..6a663e941 100644 --- a/structure/class/range-add-range-min.hpp +++ b/structure/class/range-add-range-min.hpp @@ -1,11 +1,14 @@ #pragma once +#include +#include + template struct RangeAddRangeMin { using S = T; using F = T; - static constexpr S op(const S& a, const S& b) { return min(a, b); } - static constexpr S e() { return numeric_limits::max(); } + static constexpr S op(const S& a, const S& b) { return std::min(a, b); } + static constexpr S e() { return std::numeric_limits::max(); } static constexpr F mapping(const S& x, const F& f) { return x + f; } static constexpr F composition(const F& f, const F& g) { return f + g; } static constexpr F id() { return {0}; } diff --git a/structure/class/range-chmin-chmax-add-range-sum.hpp b/structure/class/range-chmin-chmax-add-range-sum.hpp index 3c634d036..e1a5ea546 100644 --- a/structure/class/range-chmin-chmax-add-range-sum.hpp +++ b/structure/class/range-chmin-chmax-add-range-sum.hpp @@ -1,6 +1,12 @@ +#pragma once + +#include +#include +#include + template struct RangeChminChmaxAddRangeSum { - static constexpr T infty = numeric_limits::max() / 2 - 1; + static constexpr T infty = std::numeric_limits::max() / 2 - 1; struct MinMaxSum { T min, max, sum, minc, maxc, min2, max2, cnt; @@ -23,8 +29,8 @@ struct RangeChminChmaxAddRangeSum { if (b.min > b.max) return a; S c; - c.min = min(a.min, b.min); - c.max = max(a.max, b.max); + c.min = std::min(a.min, b.min); + c.max = std::max(a.max, b.max); c.sum = a.sum + b.sum; c.minc = 0; @@ -69,8 +75,8 @@ struct RangeChminChmaxAddRangeSum { if (f.chmin == infty && f.chmax == -infty) return x; T before_min = x.min, before_max = x.max; - x.min = min(x.min, f.chmin), x.min = max(x.min, f.chmax); - x.max = min(x.max, f.chmin), x.max = max(x.max, f.chmax); + x.min = std::min(x.min, f.chmin), x.min = std::max(x.min, f.chmax); + x.max = std::min(x.max, f.chmin), x.max = std::max(x.max, f.chmax); if (x.min == x.max) { x.sum = x.max * x.cnt; @@ -92,9 +98,9 @@ struct RangeChminChmaxAddRangeSum { static constexpr F composition(F f, const F& g) { f.add += g.add, f.chmax += g.add, f.chmin += g.add; - f.chmin = min(f.chmin, g.chmin); - f.chmax = min(f.chmax, g.chmin); - f.chmax = max(f.chmax, g.chmax); + f.chmin = std::min(f.chmin, g.chmin); + f.chmax = std::min(f.chmax, g.chmin); + f.chmax = std::max(f.chmax, g.chmax); return f; } @@ -105,3 +111,8 @@ struct RangeChminChmaxAddRangeSum { static constexpr F chmax(T x) { return {0, infty, x}; } static constexpr F add(T x) { return {x, infty, -infty}; } }; +#pragma once + +#include +#include +#include diff --git a/structure/others/slope-trick.hpp b/structure/others/slope-trick.hpp index 463969cfc..098b5356b 100644 --- a/structure/others/slope-trick.hpp +++ b/structure/others/slope-trick.hpp @@ -1,3 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + /** * @brief Slope-Trick * @@ -5,11 +14,11 @@ */ template struct SlopeTrick { - const T INF = numeric_limits::max() / 3; + const T INF = std::numeric_limits::max() / 3; T min_f; - priority_queue, less<> > L; - priority_queue, greater<> > R; + std::priority_queue, std::less<> > L; + std::priority_queue, std::greater<> > R; T add_l, add_r; private: @@ -43,7 +52,7 @@ struct SlopeTrick { return val; } - size_t size() { return L.size() + R.size(); } + std::size_t size() { return L.size() + R.size(); } public: SlopeTrick() : min_f(0), add_l(0), add_r(0) {} @@ -61,7 +70,7 @@ struct SlopeTrick { // add \_ // f(x) += max(a - x, 0) void add_a_minus_x(const T& a) { - min_f += max(T(0), a - top_R()); + min_f += std::max(T(0), a - top_R()); push_R(a); push_L(pop_R()); } @@ -69,7 +78,7 @@ struct SlopeTrick { // add _/ // f(x) += max(x - a, 0) void add_x_minus_a(const T& a) { - min_f += max(T(0), top_L() - a); + min_f += std::max(T(0), top_L() - a); push_L(a); push_R(pop_L()); } @@ -109,21 +118,21 @@ struct SlopeTrick { T get(const T& x) { T ret = min_f; while (not L.empty()) { - ret += max(T(0), pop_L() - x); + ret += std::max(T(0), pop_L() - x); } while (not R.empty()) { - ret += max(T(0), x - pop_R()); + ret += std::max(T(0), x - pop_R()); } return ret; } void merge(SlopeTrick& st) { if (st.size() > size()) { - swap(st.L, L); - swap(st.R, R); - swap(st.add_l, add_l); - swap(st.add_r, add_r); - swap(st.min_f, min_f); + std::swap(st.L, L); + std::swap(st.R, R); + std::swap(st.add_l, add_l); + std::swap(st.add_r, add_r); + std::swap(st.min_f, min_f); } while (not st.R.empty()) { add_x_minus_a(st.pop_R()); diff --git a/structure/others/sqrt-decomposition.hpp b/structure/others/sqrt-decomposition.hpp index b35b7c38e..9db1385a1 100644 --- a/structure/others/sqrt-decomposition.hpp +++ b/structure/others/sqrt-decomposition.hpp @@ -1,39 +1,53 @@ +#pragma once + +#include +#include +#include +#include + +#pragma once + +#include +#include +#include +#include + template struct SqrtDecomposition { - vector block_add, elem_add; - vector block_pos; - vector data, lsum; - vector > sum; + std::vector block_add, elem_add; + std::vector block_pos; + std::vector data, lsum; + std::vector > sum; int N, B, K; E L; SqrtDecomposition(int N, E L = 0) : N(N), L(L) { // find the sum of L or more in the interval - B = (int)sqrt(N); + B = (int)std::sqrt(N); K = (N + B - 1) / B; block_add.assign(K, 0); block_pos.resize(N); for (int k = 0; k < K; k++) { - for (int i = k * B; i < min((k + 1) * B, N); i++) block_pos[i] = k; + for (int i = k * B; i < std::min((k + 1) * B, N); i++) block_pos[i] = k; } elem_add.assign(N, 0); data.assign(N, 0); - sum.assign(K, vector(B, 0)); + sum.assign(K, std::vector(B, 0)); lsum.assign(K, 0); } - void build(const vector& add, const vector& dat) { + void build(const std::vector& add, const std::vector& dat) { assert(add.size() == elem_add.size()); assert(dat.size() == data.size()); elem_add = add; data = dat; for (int k = 0; k < K; k++) { E tap = elem_add[k * B]; - for (int i = k * B; i < min((k + 1) * B, N); i++) - tap = min(tap, elem_add[i]); + for (int i = k * B; i < std::min((k + 1) * B, N); i++) + tap = std::min(tap, elem_add[i]); block_add[k] = tap; - for (int i = k * B; i < min((k + 1) * B, N); i++) { + for (int i = k * B; i < std::min((k + 1) * B, N); i++) { elem_add[i] -= block_add[k]; set(i, dat[i]); } @@ -62,7 +76,7 @@ struct SqrtDecomposition { void add(int a, int b) { for (int k = 0; k < K; k++) { int l = k * B; - int r = min(l + B, N); + int r = std::min(l + B, N); if (r <= a || b <= l) { } else if (a <= l && r <= b) { @@ -71,7 +85,7 @@ struct SqrtDecomposition { lsum[k] += sum[k][L - block_add[k]]; } } else { - for (int i = max(a, l); i < min(b, r); i++) { + for (int i = std::max(a, l); i < std::min(b, r); i++) { del(i); elem_add[i]++; set(i); @@ -83,7 +97,7 @@ struct SqrtDecomposition { void sub(int a, int b) { for (int k = 0; k < K; k++) { int l = k * B; - int r = min(l + B, N); + int r = std::min(l + B, N); if (r <= a || b <= l) { } else if (a <= l && r <= b) { @@ -96,12 +110,12 @@ struct SqrtDecomposition { lsum[k] -= sum[k][L - block_add[k]]; } block_add[k]--; - for (int i = l; i < max(a, l); i++) { + for (int i = l; i < std::max(a, l); i++) { del(i); elem_add[i]++; set(i); } - for (int i = min(b, r); i < r; i++) { + for (int i = std::min(b, r); i < r; i++) { del(i); elem_add[i]++; set(i); @@ -114,7 +128,7 @@ struct SqrtDecomposition { T ret = 0; for (int k = 0; k < K; k++) { int l = k * B; - int r = min(l + B, N); + int r = std::min(l + B, N); if (r <= a || b <= l) { } else if (a <= l && r <= b) { @@ -122,7 +136,7 @@ struct SqrtDecomposition { ret += sum[k][x - block_add[k]]; } } else { - for (int i = max(a, l); i < min(b, r); i++) { + for (int i = std::max(a, l); i < std::min(b, r); i++) { if (block_add[k] + elem_add[i] == x) ret += data[i]; } } @@ -134,13 +148,13 @@ struct SqrtDecomposition { T ret = 0; for (int k = 0; k < K; k++) { int l = k * B; - int r = min(l + B, N); + int r = std::min(l + B, N); if (r <= a || b <= l) { } else if (a <= l && r <= b) { ret += lsum[k]; } else { - for (int i = max(a, l); i < min(b, r); i++) { + for (int i = std::max(a, l); i < std::min(b, r); i++) { if (block_add[k] + elem_add[i] >= L) ret += data[i]; } } diff --git a/structure/others/union-rectangle.hpp b/structure/others/union-rectangle.hpp index 988190d94..1fa3be7f1 100644 --- a/structure/others/union-rectangle.hpp +++ b/structure/others/union-rectangle.hpp @@ -1,10 +1,16 @@ +#pragma once + +#include +#include +#include + template struct UnionRectangle { - map data; - int64 sum; + std::map data; + std::int64_t sum; UnionRectangle() : sum(0) { - const T INF = numeric_limits::max(); + const T INF = std::numeric_limits::max(); data[0] = INF; data[INF] = 0; } @@ -22,5 +28,5 @@ struct UnionRectangle { data[x] = y; } - int64 get() { return sum; } + std::int64_t get() { return sum; } }; diff --git a/test/unittest/self-contained-header-migration.test.cpp b/test/unittest/self-contained-header-migration.test.cpp new file mode 100644 index 000000000..965868006 --- /dev/null +++ b/test/unittest/self-contained-header-migration.test.cpp @@ -0,0 +1,79 @@ +// competitive-verifier: STANDALONE + +#include +#include +#include +#include + +#include "../../dp/cumulative-sum-2d.hpp" +#include "../../dp/cumulative-sum.hpp" +#include "../../dp/edit-distance.hpp" +#include "../../dp/knapsack-01-2.hpp" +#include "../../dp/knapsack-01.hpp" +#include "../../dp/knapsack-limitations.hpp" +#include "../../dp/knapsack.hpp" +#include "../../dp/largest-rectangle.hpp" +#include "../../dp/longest-increasing-subsequence.hpp" +#include "../../dp/monotone-minima.hpp" +#include "../../structure/class/act.hpp" +#include "../../structure/class/acted-monoid.hpp" +#include "../../structure/class/affine.hpp" +#include "../../structure/class/beats-monoid.hpp" +#include "../../structure/class/monoid.hpp" +#include "../../structure/class/range-add-range-min.hpp" +#include "../../structure/class/range-chmin-chmax-add-range-sum.hpp" +#include "../../structure/others/slope-trick.hpp" +#include "../../structure/others/sqrt-decomposition.hpp" +#include "../../structure/others/union-rectangle.hpp" + +int main() { + CumulativeSum sum(3); + sum.add(0, 2), sum.add(2, 5), sum.build(); + assert(sum.fold(0, 3) == 7); + + CumulativeSum2D sum_2d(2, 2); + sum_2d.add(0, 1, 3), sum_2d.add(1, 0, 4), sum_2d.build(); + assert(sum_2d.query(0, 0, 2, 2) == 7); + assert(edit_distance("kitten", "sitting") == 3); + assert(knapsack_01(std::vector{2}, std::vector{5}, 2, -1)[2] == 5); + assert(knapsack_01_2(std::vector{2}, std::vector{5}, 2) == 5); + assert(knapsack(std::vector{2}, std::vector{5}, 2, -1)[2] == 5); + assert(knapsack_limitations(std::vector{2}, std::vector{2}, + std::vector{5}, 4, -1)[4] == 10); + assert(largest_rectangle(std::vector{2, 1, 2}) == 3); + assert(longest_increasing_subsequence(std::vector{3, 1, 2}, true) == 2); + auto minima = monotone_minima( + 2, 2, [](int i, int j) { return (i - j) * (i - j); }); + assert(minima[0].first == 0 && minima[1].first == 1); + + Affine f(2, 3), g(4, 5); + assert(Affine::op(f, g).eval(1) == 25); + assert(RangeAddRangeMin::op(3, 1) == 1); + assert(RangeChminChmaxAddRangeSum::set(4).sum == 4); + + auto monoid = + LambdaMonoid([](int a, int b) { return a + b; }, [] { return 0; }); + assert(monoid.op(2, 3) == 5 && monoid.e() == 0); + auto act = LambdaAct([](int a, int b) { return a + b; }, [] { return 0; }); + assert(act.composition(2, 3) == 5 && act.id() == 0); + auto acted_monoid = + LambdaActedMonoid([](int a, int b) { return a + b; }, [] { return 0; }, + [](int x, int f) { return x + f; }, + [](int f, int g) { return f + g; }, [] { return 0; }); + assert(acted_monoid.mapping(2, 3) == 5); + auto beats = LambdaBeatsMonoid( + [](int a, int b) { return a + b; }, [](int) { return false; }, + [] { return 0; }, [](int x, int f) { return x + f; }, + [](int f, int g) { return f + g; }, [] { return 0; }); + assert(beats.mapping(2, 3) == 5 && !beats.fail(0)); + + SlopeTrick slope; + slope.add_abs(3); + assert(slope.get(3) == 0); + UnionRectangle rectangle; + rectangle.add_point(2, 3); + assert(rectangle.get() == 6); + SqrtDecomposition decomposition(2); + decomposition.build({0, 1}, {4, 5}); + assert(decomposition.query(0, 2, 1) == 5); +} From f09be947def0e43085cb909efb0af55d7261fc9c Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 06:54:42 +0000 Subject: [PATCH 02/16] Migrate 40 more headers to self-contained includes --- SELF_CONTAINED_HEADER_MIGRATION.md | 63 ++++++++------- dp/divide-and-conquer-optimization.hpp | 15 ++-- dp/knapsack-limitations-2.hpp | 33 +++++--- dp/online-offline-dp.hpp | 42 +++++----- graph/graph-template.hpp | 20 +++-- graph/shortest-path/bellman-ford.hpp | 18 +++-- graph/shortest-path/bfs.hpp | 17 ++-- graph/shortest-path/dijkstra.hpp | 23 ++++-- graph/shortest-path/grid-bfs.hpp | 19 +++-- graph/shortest-path/warshall-floyd.hpp | 13 ++- math/combinatorics/binomial-table.hpp | 8 +- math/combinatorics/enumeration.hpp | 16 ++-- math/combinatorics/montmort.hpp | 8 +- math/combinatorics/partition-table.hpp | 8 +- .../sum-of-arithmetic-sequence.hpp | 2 + .../sum-of-geometric-sequence.hpp | 8 +- math/matrix/matrix.hpp | 41 ++++++---- math/matrix/square-matrix.hpp | 45 ++++++----- math/number-theory/convert-base.hpp | 14 +++- math/number-theory/divisor.hpp | 14 +++- math/number-theory/enumerate-quotients.hpp | 10 ++- math/number-theory/euler-phi-table.hpp | 8 +- math/number-theory/euler-phi.hpp | 2 + math/number-theory/extgcd.hpp | 2 + math/number-theory/is-prime.hpp | 8 +- math/number-theory/kth-root-integer.hpp | 10 ++- math/number-theory/moebius-mu-table.hpp | 8 +- math/number-theory/prime-factor.hpp | 11 ++- math/rational/rational.hpp | 9 ++- other/ceil-div.hpp | 6 +- other/chrono-timer.hpp | 15 ++-- other/compress.hpp | 34 +++++--- other/dice.hpp | 8 +- other/floor-div.hpp | 6 +- other/printer.hpp | 23 ++++-- other/random-number-generator.hpp | 11 ++- other/vector-pool.hpp | 10 ++- other/xor-shift.hpp | 4 + scripts/self-contained-headers.txt | 40 ++++++++++ string/manacher.hpp | 10 ++- string/z-algorithm.hpp | 19 +++-- structure/class/act.hpp | 2 - structure/class/acted-monoid.hpp | 2 - structure/class/beats-monoid.hpp | 2 - .../self-contained-header-migration.test.cpp | 79 +++++++++++++++++++ 45 files changed, 546 insertions(+), 220 deletions(-) diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index 0fdac5f70..07c7e6683 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -22,7 +22,7 @@ | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 40 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 80 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -94,35 +94,42 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null ## 移行履歴 -| 日付 | 対象 | 備考 | -| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| 2026-08-04 | `structure/others/sparse-table.hpp` | 標準 include と `std::` 修飾 | -| 2026-08-04 | `structure/others/disjoint-sparse-table.hpp` | 標準 include と `std::` 修飾 | -| 2026-08-04 | `structure/others/plus-minus-one-rmq.hpp` | Sparse Table 依存を明示 | -| 2026-08-04 | `structure/others/queue-operate-aggregation.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/deque-operate-aggregation.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/abstract-binary-indexed-tree.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/binary-indexed-tree.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/persistent-array.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/priority-sum-structure.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/others/linear-rmq.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/union-find.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/weighted-union-find.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/union-find-undo.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/partially-persistent-union-find.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/union-find/persistent-union-find.hpp` | Persistent Array 依存を明示 | -| 2026-08-04 | `structure/union-find/bipartite-graph.hpp` | Union Find 依存を明示 | -| 2026-08-04 | `structure/heap/erasable-heap.hpp` | 標準依存を補完 | -| 2026-08-04 | `structure/heap/leftist-heap.hpp` | 標準依存を明示 | -| 2026-08-04 | `structure/heap/persistent-leftist-heap.hpp` | Leftist Heap 依存を明示 | -| 2026-08-04 | `structure/heap/skew-heap.hpp` | 標準依存を明示 | -| 2026-08-10 | `dp/cumulative-sum-2d.hpp`、`dp/cumulative-sum.hpp`、`dp/edit-distance.hpp`、`dp/knapsack-01-2.hpp`、`dp/knapsack-01.hpp`、`dp/knapsack-limitations.hpp`、`dp/knapsack.hpp`、`dp/largest-rectangle.hpp`、`dp/longest-increasing-subsequence.hpp`、`dp/monotone-minima.hpp` | 標準 include と `std::` 修飾 | -| 2026-08-10 | `structure/class/act.hpp`、`structure/class/acted-monoid.hpp`、`structure/class/affine.hpp`、`structure/class/beats-monoid.hpp`、`structure/class/monoid.hpp`、`structure/class/range-add-range-min.hpp`、`structure/class/range-chmin-chmax-add-range-sum.hpp` | 標準 include と `std::` 修飾 | -| 2026-08-10 | `structure/others/slope-trick.hpp`、`structure/others/sqrt-decomposition.hpp`、`structure/others/union-rectangle.hpp` | 標準 include と `std::` 修飾 | +| 日付 | 対象 | 備考 | +| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| 2026-08-04 | `structure/others/sparse-table.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-04 | `structure/others/disjoint-sparse-table.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-04 | `structure/others/plus-minus-one-rmq.hpp` | Sparse Table 依存を明示 | +| 2026-08-04 | `structure/others/queue-operate-aggregation.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/deque-operate-aggregation.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/abstract-binary-indexed-tree.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/binary-indexed-tree.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/persistent-array.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/priority-sum-structure.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/others/linear-rmq.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/union-find.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/weighted-union-find.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/union-find-undo.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/partially-persistent-union-find.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/union-find/persistent-union-find.hpp` | Persistent Array 依存を明示 | +| 2026-08-04 | `structure/union-find/bipartite-graph.hpp` | Union Find 依存を明示 | +| 2026-08-04 | `structure/heap/erasable-heap.hpp` | 標準依存を補完 | +| 2026-08-04 | `structure/heap/leftist-heap.hpp` | 標準依存を明示 | +| 2026-08-04 | `structure/heap/persistent-leftist-heap.hpp` | Leftist Heap 依存を明示 | +| 2026-08-04 | `structure/heap/skew-heap.hpp` | 標準依存を明示 | +| 2026-08-10 | `dp/cumulative-sum-2d.hpp`、`dp/cumulative-sum.hpp`、`dp/edit-distance.hpp`、`dp/knapsack-01-2.hpp`、`dp/knapsack-01.hpp`、`dp/knapsack-limitations.hpp`、`dp/knapsack.hpp`、`dp/largest-rectangle.hpp`、`dp/longest-increasing-subsequence.hpp`、`dp/monotone-minima.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `structure/class/act.hpp`、`structure/class/acted-monoid.hpp`、`structure/class/affine.hpp`、`structure/class/beats-monoid.hpp`、`structure/class/monoid.hpp`、`structure/class/range-add-range-min.hpp`、`structure/class/range-chmin-chmax-add-range-sum.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `structure/others/slope-trick.hpp`、`structure/others/sqrt-decomposition.hpp`、`structure/others/union-rectangle.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `dp/divide-and-conquer-optimization.hpp`、`dp/knapsack-limitations-2.hpp`、`dp/online-offline-dp.hpp` | 移行済みヘッダーへの依存を明示 | +| 2026-08-10 | `graph/graph-template.hpp`、`graph/shortest-path/bellman-ford.hpp`、`graph/shortest-path/bfs.hpp`、`graph/shortest-path/dijkstra.hpp`、`graph/shortest-path/grid-bfs.hpp`、`graph/shortest-path/warshall-floyd.hpp` | グラフ共通型と標準 include を明示 | +| 2026-08-10 | `math/combinatorics/` の6ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `math/matrix/matrix.hpp`、`math/matrix/square-matrix.hpp`、`math/rational/rational.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `math/number-theory/` の11ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `other/` の9ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `string/manacher.hpp`、`string/z-algorithm.hpp` | 標準 include と `std::` 修飾 | ## 次の候補 次の候補として、プロジェクト内ヘッダーへの依存がない -`structure/others/generalized-slope-trick.hpp` と、標準依存を補完しやすい -`structure/others/permutation-tree.hpp` を検討する。その後も依存関係の葉に近い +`structure/others/generalized-slope-trick.hpp`、`structure/others/permutation-tree.hpp`、 +および geometry の基礎ヘッダー群を検討する。その後も依存関係の葉に近い ヘッダーから進め、1コミットの変更範囲を小さく保つ。 diff --git a/dp/divide-and-conquer-optimization.hpp b/dp/divide-and-conquer-optimization.hpp index a59d448aa..b83f6d9d2 100644 --- a/dp/divide-and-conquer-optimization.hpp +++ b/dp/divide-and-conquer-optimization.hpp @@ -1,13 +1,18 @@ +#pragma once + +#include +#include + #include "monotone-minima.hpp" -template > -vector > divide_and_conquer_optimization( - int H, int W, T INF, const function& f, +template > +std::vector > divide_and_conquer_optimization( + int H, int W, T INF, const std::function& f, const Compare& comp = Compare()) { - vector > dp(H + 1, vector(W + 1, INF)); + std::vector > dp(H + 1, std::vector(W + 1, INF)); dp[0][0] = 0; for (int i = 1; i <= H; i++) { - function get_cost = [&](int y, int x) { + std::function get_cost = [&](int y, int x) { if (x >= y) return INF; return dp[i - 1][x] + f(x, y); }; diff --git a/dp/knapsack-limitations-2.hpp b/dp/knapsack-limitations-2.hpp index c29ae4b62..59e60f7ff 100644 --- a/dp/knapsack-limitations-2.hpp +++ b/dp/knapsack-limitations-2.hpp @@ -1,35 +1,42 @@ +#pragma once + +#include +#include +#include +#include + #include "knapsack-limitations.hpp" template -T knapsack_limitations(const vector& w, const vector& m, - const vector& v, const T& W) { +T knapsack_limitations(const std::vector& w, const std::vector& m, + const std::vector& v, const T& W) { const int N = (int)w.size(); - auto v_max = *max_element(begin(v), end(v)); + auto v_max = *std::max_element(v.begin(), v.end()); if (v_max == 0) return 0; - vector ma(N); - vector mb(N); + std::vector ma(N); + std::vector mb(N); for (int i = 0; i < N; i++) { - ma[i] = min(m[i], v_max - 1); + ma[i] = std::min(m[i], v_max - 1); mb[i] = m[i] - ma[i]; } T sum = 0; for (int i = 0; i < N; i++) sum += ma[i] * v[i]; - auto dp = knapsack_limitations(v, ma, w, sum, T(-1), less<>()); - vector ord(N); - iota(begin(ord), end(ord), 0); - sort(begin(ord), end(ord), - [&](int a, int b) { return v[a] * w[b] > v[b] * w[a]; }); + auto dp = knapsack_limitations(v, ma, w, sum, T(-1), std::less<>()); + std::vector ord(N); + std::iota(ord.begin(), ord.end(), 0); + std::sort(ord.begin(), ord.end(), + [&](int a, int b) { return v[a] * w[b] > v[b] * w[a]; }); T ret = T(); for (int i = 0; i < dp.size(); i++) { if (dp[i] > W || dp[i] == -1) continue; T rest = W - dp[i], cost = i; for (auto& p : ord) { - auto get = min(mb[p], rest / w[p]); + auto get = std::min(mb[p], rest / w[p]); if (get <= 0) continue; cost += get * v[p]; rest -= get * w[p]; } - ret = max(ret, cost); + ret = std::max(ret, cost); } return ret; } diff --git a/dp/online-offline-dp.hpp b/dp/online-offline-dp.hpp index f48b9a8a7..d2cdf6d41 100644 --- a/dp/online-offline-dp.hpp +++ b/dp/online-offline-dp.hpp @@ -1,27 +1,33 @@ +#pragma once + +#include +#include + #include "monotone-minima.hpp" -template > -vector online_offline_dp(int W, const function& f, - const Compare& comp = Compare()) { - vector dp(W + 1); - vector isset(W + 1); +template > +std::vector online_offline_dp(int W, const std::function& f, + const Compare& comp = Compare()) { + std::vector dp(W + 1); + std::vector isset(W + 1); int y_base = -1, x_base = -1; - function get_cost = + std::function get_cost = [&](int y, int x) { // return dp[0, x+x_base)+f[x+x_base, y+y_base) return dp[x + x_base] + f(x + x_base, y + y_base); }; - function induce = [&](int l, int m, - int r) { // dp[l, m) -> dp[m, r) - x_base = l, y_base = m; - auto ret = monotone_minima(r - m, m - l, get_cost, comp); - for (int i = 0; i < ret.size(); i++) { - if (!isset[m + i] || comp(ret[i].second, dp[m + i])) { - isset[m + i] = true; - dp[m + i] = ret[i].second; - } - } - }; - function dfs = [&](int l, int r) { + std::function induce = + [&](int l, int m, + int r) { // dp[l, m) -> dp[m, r) + x_base = l, y_base = m; + auto ret = monotone_minima(r - m, m - l, get_cost, comp); + for (int i = 0; i < ret.size(); i++) { + if (!isset[m + i] || comp(ret[i].second, dp[m + i])) { + isset[m + i] = true; + dp[m + i] = ret[i].second; + } + } + }; + std::function dfs = [&](int l, int r) { if (l + 1 == r) { x_base = l, y_base = l; T cst = l ? get_cost(0, -1) : 0; diff --git a/graph/graph-template.hpp b/graph/graph-template.hpp index d85f145ae..65ba34d58 100644 --- a/graph/graph-template.hpp +++ b/graph/graph-template.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + template struct Edge { int from, to; @@ -16,14 +20,14 @@ struct Edge { template struct Graph { - vector > > g; + std::vector > > g; int es; Graph() = default; explicit Graph(int n) : g(n), es(0) {} - size_t size() const { return g.size(); } + std::size_t size() const { return g.size(); } void add_directed_edge(int from, int to, T cost = 1) { g[from].emplace_back(from, to, cost, es++); @@ -38,11 +42,11 @@ struct Graph { bool directed = false) { for (int i = 0; i < M; i++) { int a, b; - cin >> a >> b; + std::cin >> a >> b; a += padding; b += padding; T c = T(1); - if (weighted) cin >> c; + if (weighted) std::cin >> c; if (directed) add_directed_edge(a, b, c); else @@ -50,10 +54,12 @@ struct Graph { } } - inline vector >& operator[](const int& k) { return g[k]; } + inline std::vector >& operator[](const int& k) { return g[k]; } - inline const vector >& operator[](const int& k) const { return g[k]; } + inline const std::vector >& operator[](const int& k) const { + return g[k]; + } }; template -using Edges = vector >; +using Edges = std::vector >; diff --git a/graph/shortest-path/bellman-ford.hpp b/graph/shortest-path/bellman-ford.hpp index 14830607e..00bf10777 100644 --- a/graph/shortest-path/bellman-ford.hpp +++ b/graph/shortest-path/bellman-ford.hpp @@ -1,18 +1,24 @@ +#pragma once + +#include +#include +#include + #include "../graph-template.hpp" template -vector bellman_ford(const Edges& edges, int n, int s) { - const auto INF = numeric_limits::max(); - const auto M_INF = numeric_limits::min(); - vector dist(n, INF); +std::vector bellman_ford(const Edges& edges, int n, int s) { + const auto INF = std::numeric_limits::max(); + const auto M_INF = std::numeric_limits::min(); + std::vector dist(n, INF); dist[s] = 0; for (int i = 0; i < n - 1; i++) { for (auto& e : edges) { if (dist[e.from] == INF) continue; - dist[e.to] = min(dist[e.to], dist[e.from] + e.cost); + dist[e.to] = std::min(dist[e.to], dist[e.from] + e.cost); } } - vector negative(n); + std::vector negative(n); for (int i = 0; i < n; i++) { for (auto& e : edges) { if (dist[e.from] == INF) continue; diff --git a/graph/shortest-path/bfs.hpp b/graph/shortest-path/bfs.hpp index 4ee888de1..7f656e809 100644 --- a/graph/shortest-path/bfs.hpp +++ b/graph/shortest-path/bfs.hpp @@ -1,20 +1,25 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" /** * @brief BFS(幅優先探索) */ template -vector bfs(const Graph& g, int s) { +std::vector bfs(const Graph& g, int s) { T max_cost = 0, beet = 0; for (auto& es : g.g) { - for (auto& e : es) max_cost = max(max_cost, e.cost); + for (auto& e : es) max_cost = std::max(max_cost, e.cost); } ++max_cost; - const auto INF = numeric_limits::max(); - vector dist(g.size(), INF); - vector > ques(max_cost + 1); + const auto INF = std::numeric_limits::max(); + std::vector dist(g.size(), INF); + std::vector > ques(max_cost + 1); dist[s] = 0; ques[0].emplace(s); for (T cost = 0; cost <= beet; cost++) { @@ -28,7 +33,7 @@ vector bfs(const Graph& g, int s) { if (dist[e.to] <= next_cost) continue; ; dist[e.to] = next_cost; - beet = max(beet, dist[e.to]); + beet = std::max(beet, dist[e.to]); ques[dist[e.to] % max_cost].emplace(e.to); } } diff --git a/graph/shortest-path/dijkstra.hpp b/graph/shortest-path/dijkstra.hpp index c35c08906..c7d53f40c 100644 --- a/graph/shortest-path/dijkstra.hpp +++ b/graph/shortest-path/dijkstra.hpp @@ -1,5 +1,12 @@ #pragma once +#include +#include +#include +#include +#include +#include + #include "../graph-template.hpp" /** @@ -8,23 +15,23 @@ */ template struct ShortestPath { - vector dist; - vector from, id; + std::vector dist; + std::vector from, id; }; template ShortestPath dijkstra(const Graph& g, int s) { - const auto INF = numeric_limits::max(); - vector dist(g.size(), INF); - vector from(g.size(), -1), id(g.size(), -1); - using Pi = pair; - priority_queue, greater<> > que; + const auto INF = std::numeric_limits::max(); + std::vector dist(g.size(), INF); + std::vector from(g.size(), -1), id(g.size(), -1); + using Pi = std::pair; + std::priority_queue, std::greater<> > que; dist[s] = 0; que.emplace(dist[s], s); while (!que.empty()) { T cost; int idx; - tie(cost, idx) = que.top(); + std::tie(cost, idx) = que.top(); que.pop(); if (dist[idx] < cost) continue; for (auto& e : g[idx]) { diff --git a/graph/shortest-path/grid-bfs.hpp b/graph/shortest-path/grid-bfs.hpp index 8d7338b63..dcb8c3091 100644 --- a/graph/shortest-path/grid-bfs.hpp +++ b/graph/shortest-path/grid-bfs.hpp @@ -1,8 +1,17 @@ -vector > grid_bfs(vector& s, char start, - const string& wall = "#") { +#pragma once + +#include +#include +#include +#include +#include + +std::vector > grid_bfs(std::vector& s, char start, + const std::string& wall = "#") { const int vx[] = {0, 1, 0, -1}, vy[] = {1, 0, -1, 0}; - vector > min_cost(s.size(), vector(s[0].size(), -1)); - queue > que; + std::vector > min_cost(s.size(), + std::vector(s[0].size(), -1)); + std::queue > que; for (int i = 0; i < s.size(); i++) { for (int j = 0; j < s[i].size(); j++) { if (s[i][j] == start) { @@ -18,7 +27,7 @@ vector > grid_bfs(vector& s, char start, int ny = p.first + vy[i], nx = p.second + vx[i]; if (nx < 0 || ny < 0 || nx >= s[0].size() || ny >= s.size()) continue; if (min_cost[ny][nx] != -1) continue; - if (wall.find(s[ny][nx]) != string::npos) continue; + if (wall.find(s[ny][nx]) != std::string::npos) continue; min_cost[ny][nx] = min_cost[p.first][p.second] + 1; que.emplace(ny, nx); } diff --git a/graph/shortest-path/warshall-floyd.hpp b/graph/shortest-path/warshall-floyd.hpp index 4ccc9d63a..0ed2eb489 100644 --- a/graph/shortest-path/warshall-floyd.hpp +++ b/graph/shortest-path/warshall-floyd.hpp @@ -1,13 +1,18 @@ +#pragma once + +#include +#include + /** * @brief Warshall Floyd(全点対間最短路) */ template void warshall_floyd(Matrix& g, T INF) { - for (size_t k = 0; k < g.size(); k++) { - for (size_t i = 0; i < g.size(); i++) { - for (size_t j = 0; j < g.size(); j++) { + for (std::size_t k = 0; k < g.size(); k++) { + for (std::size_t i = 0; i < g.size(); i++) { + for (std::size_t j = 0; j < g.size(); j++) { if (g[i][k] == INF || g[k][j] == INF) continue; - g[i][j] = min(g[i][j], g[i][k] + g[k][j]); + g[i][j] = std::min(g[i][j], g[i][k] + g[k][j]); } } } diff --git a/math/combinatorics/binomial-table.hpp b/math/combinatorics/binomial-table.hpp index b10e82981..4dccf03a1 100644 --- a/math/combinatorics/binomial-table.hpp +++ b/math/combinatorics/binomial-table.hpp @@ -1,10 +1,14 @@ +#pragma once + +#include + /** * @brief Binomial Table(二項係数テーブル) * */ template -vector > binomial_table(int N) { - vector > mat(N + 1, vector(N + 1)); +std::vector > binomial_table(int N) { + std::vector > mat(N + 1, std::vector(N + 1)); for (int i = 0; i <= N; i++) { for (int j = 0; j <= i; j++) { if (j == 0 || j == i) diff --git a/math/combinatorics/enumeration.hpp b/math/combinatorics/enumeration.hpp index c90d9cb56..5eb457c26 100644 --- a/math/combinatorics/enumeration.hpp +++ b/math/combinatorics/enumeration.hpp @@ -1,14 +1,20 @@ +#pragma once + +#include +#include +#include + /** * @brief Enumeration(組み合わせ) */ template struct Enumeration { private: - static vector _fact, _finv, _inv; + static std::vector _fact, _finv, _inv; inline static void expand(size_t sz) { if (_fact.size() < sz + 1) { - int pre_sz = max(1, (int)_fact.size()); + int pre_sz = std::max(1, (int)_fact.size()); _fact.resize(sz + 1, T(1)); _finv.resize(sz + 1, T(1)); _inv.resize(sz + 1, T(1)); @@ -60,8 +66,8 @@ struct Enumeration { }; template -vector Enumeration::_fact = vector(); +std::vector Enumeration::_fact = std::vector(); template -vector Enumeration::_finv = vector(); +std::vector Enumeration::_finv = std::vector(); template -vector Enumeration::_inv = vector(); +std::vector Enumeration::_inv = std::vector(); diff --git a/math/combinatorics/montmort.hpp b/math/combinatorics/montmort.hpp index 1a738e3b9..c11a7599c 100644 --- a/math/combinatorics/montmort.hpp +++ b/math/combinatorics/montmort.hpp @@ -1,10 +1,14 @@ +#pragma once + +#include + /** * @brief Montmort-Number(モンモール数) * */ template -vector montmort(int N) { - vector dp(N + 1); +std::vector montmort(int N) { + std::vector dp(N + 1); for (int k = 2; k <= N; k++) { dp[k] = dp[k - 1] * k; if (k & 1) diff --git a/math/combinatorics/partition-table.hpp b/math/combinatorics/partition-table.hpp index 617eaa3f6..3b8efd77b 100644 --- a/math/combinatorics/partition-table.hpp +++ b/math/combinatorics/partition-table.hpp @@ -1,10 +1,14 @@ +#pragma once + +#include + /** * @brief Partition Table(分割数テーブル) * */ template -vector > partition_table(int n, int k) { - vector > dp(n + 1, vector(k + 1)); +std::vector > partition_table(int n, int k) { + std::vector > dp(n + 1, std::vector(k + 1)); dp[0][0] = 1; for (int i = 0; i <= n; i++) { for (int j = 1; j <= k; j++) { diff --git a/math/combinatorics/sum-of-arithmetic-sequence.hpp b/math/combinatorics/sum-of-arithmetic-sequence.hpp index bb4f91a59..36e90327a 100644 --- a/math/combinatorics/sum-of-arithmetic-sequence.hpp +++ b/math/combinatorics/sum-of-arithmetic-sequence.hpp @@ -1,3 +1,5 @@ +#pragma once + /** * @brief Sum of Arithmetic Sequence(等差数列の和) */ diff --git a/math/combinatorics/sum-of-geometric-sequence.hpp b/math/combinatorics/sum-of-geometric-sequence.hpp index 8baecf7c9..1100da6d8 100644 --- a/math/combinatorics/sum-of-geometric-sequence.hpp +++ b/math/combinatorics/sum-of-geometric-sequence.hpp @@ -1,8 +1,14 @@ +#pragma once + +#include +#include + /** * @brief Sum of Geometric Sequence(等比数列の和) */ template -Mint sum_of_geometric_sequence(const Mint& a, const Mint& r, const int64_t& n) { +Mint sum_of_geometric_sequence(const Mint& a, const Mint& r, + const std::int64_t& n) { assert(r != Mint(0)); return r == Mint(1) ? a * n : a * (r.pow(n) - 1) / (r - 1); } diff --git a/math/matrix/matrix.hpp b/math/matrix/matrix.hpp index 228574c71..fb6c445f7 100644 --- a/math/matrix/matrix.hpp +++ b/math/matrix/matrix.hpp @@ -1,37 +1,44 @@ +#pragma once + +#include +#include +#include +#include + template struct Matrix { - vector > A; + std::vector > A; Matrix() {} - Matrix(const vector >& A) : A(A) {} + Matrix(const std::vector >& A) : A(A) {} - Matrix(size_t n, size_t m) : A(n, vector(m, 0)) {} + Matrix(std::size_t n, std::size_t m) : A(n, std::vector(m, 0)) {} - Matrix(size_t n) : A(n, vector(n, 0)) {}; + Matrix(std::size_t n) : A(n, std::vector(n, 0)) {}; - size_t size() const { + std::size_t size() const { if (A.empty()) return 0; assert(A.size() == A[0].size()); return A.size(); } - size_t height() const { return (A.size()); } + std::size_t height() const { return (A.size()); } - size_t width() const { return (A[0].size()); } + std::size_t width() const { return (A[0].size()); } - inline const vector& operator[](int k) const { return (A.at(k)); } + inline const std::vector& operator[](int k) const { return (A.at(k)); } - inline vector& operator[](int k) { return (A.at(k)); } + inline std::vector& operator[](int k) { return (A.at(k)); } - static Matrix I(size_t n) { + static Matrix I(std::size_t n) { Matrix mat(n); for (int i = 0; i < n; i++) mat[i][i] = 1; return (mat); } Matrix& operator+=(const Matrix& B) { - size_t n = height(), m = width(); + std::size_t n = height(), m = width(); assert(n == B.height() && m == B.width()); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) (*this)[i][j] += B[i][j]; @@ -39,7 +46,7 @@ struct Matrix { } Matrix& operator-=(const Matrix& B) { - size_t n = height(), m = width(); + std::size_t n = height(), m = width(); assert(n == B.height() && m == B.width()); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) (*this)[i][j] -= B[i][j]; @@ -47,9 +54,9 @@ struct Matrix { } Matrix& operator*=(const Matrix& B) { - size_t n = height(), m = B.width(), p = width(); + std::size_t n = height(), m = B.width(), p = width(); assert(p == B.height()); - vector > C(n, vector(m, 0)); + std::vector > C(n, std::vector(m, 0)); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) for (int k = 0; k < p; k++) @@ -77,8 +84,8 @@ struct Matrix { Matrix operator^(const long long k) const { return (Matrix(*this) ^= k); } - friend ostream& operator<<(ostream& os, Matrix& p) { - size_t n = p.height(), m = p.width(); + friend std::ostream& operator<<(std::ostream& os, Matrix& p) { + std::size_t n = p.height(), m = p.width(); for (int i = 0; i < n; i++) { os << "["; for (int j = 0; j < m; j++) { @@ -100,7 +107,7 @@ struct Matrix { if (idx == -1) return (0); if (i != idx) { ret *= -1; - swap(B[i], B[idx]); + std::swap(B[i], B[idx]); } ret *= B[i][i]; T vv = B[i][i]; diff --git a/math/matrix/square-matrix.hpp b/math/matrix/square-matrix.hpp index 52c8b4659..7c663f820 100644 --- a/math/matrix/square-matrix.hpp +++ b/math/matrix/square-matrix.hpp @@ -1,31 +1,38 @@ +#pragma once + +#include +#include +#include +#include + /** * @brief Square-Matrix(正方行列) */ -template +template struct SquareMatrix { - array, N> A; + std::array, N> A; SquareMatrix() : A{{}} {} - SquareMatrix(const array, N>& A) : A(A) {} + SquareMatrix(const std::array, N>& A) : A(A) {} - size_t size() const { return N; } + std::size_t size() const { return N; } - inline const array& operator[](int k) const { return (A.at(k)); } + inline const std::array& operator[](int k) const { return (A.at(k)); } - inline array& operator[](int k) { return (A.at(k)); } + inline std::array& operator[](int k) { return (A.at(k)); } static SquareMatrix add_identity() { return SquareMatrix(); } static SquareMatrix mul_identity() { SquareMatrix mat; - for (size_t i = 0; i < N; i++) mat[i][i] = 1; + for (std::size_t i = 0; i < N; i++) mat[i][i] = 1; return mat; } SquareMatrix& operator+=(const SquareMatrix& B) { - for (size_t i = 0; i < N; i++) { - for (size_t j = 0; j < N; j++) { + for (std::size_t i = 0; i < N; i++) { + for (std::size_t j = 0; j < N; j++) { (*this)[i][j] += B[i][j]; } } @@ -33,8 +40,8 @@ struct SquareMatrix { } SquareMatrix& operator-=(const SquareMatrix& B) { - for (size_t i = 0; i < N; i++) { - for (size_t j = 0; j < N; j++) { + for (std::size_t i = 0; i < N; i++) { + for (std::size_t j = 0; j < N; j++) { (*this)[i][j] -= B[i][j]; } } @@ -42,10 +49,10 @@ struct SquareMatrix { } SquareMatrix& operator*=(const SquareMatrix& B) { - array, N> C; - for (size_t i = 0; i < N; i++) { - for (size_t j = 0; j < N; j++) { - for (size_t k = 0; k < N; k++) { + std::array, N> C; + for (std::size_t i = 0; i < N; i++) { + for (std::size_t j = 0; j < N; j++) { + for (std::size_t k = 0; k < N; k++) { C[i][j] = (C[i][j] + (*this)[i][k] * B[k][j]); } } @@ -54,7 +61,7 @@ struct SquareMatrix { return (*this); } - SquareMatrix& operator^=(uint64_t k) { + SquareMatrix& operator^=(std::uint64_t k) { SquareMatrix B = SquareMatrix::mul_identity(); while (k > 0) { if (k & 1) B *= *this; @@ -77,9 +84,11 @@ struct SquareMatrix { return SquareMatrix(*this) *= B; } - SquareMatrix operator^(uint64_t k) const { return SquareMatrix(*this) ^= k; } + SquareMatrix operator^(std::uint64_t k) const { + return SquareMatrix(*this) ^= k; + } - friend ostream& operator<<(ostream& os, SquareMatrix& p) { + friend std::ostream& operator<<(std::ostream& os, SquareMatrix& p) { for (int i = 0; i < N; i++) { os << "["; for (int j = 0; j < N; j++) { diff --git a/math/number-theory/convert-base.hpp b/math/number-theory/convert-base.hpp index 335101f86..3b3ef33cc 100644 --- a/math/number-theory/convert-base.hpp +++ b/math/number-theory/convert-base.hpp @@ -1,7 +1,13 @@ +#pragma once + +#include +#include +#include + template -vector convert_base(T x, T b) { - vector ret; - T t = 1, k = abs(b); +std::vector convert_base(T x, T b) { + std::vector ret; + T t = 1, k = std::abs(b); while (x) { ret.emplace_back((x * t) % k); if (ret.back() < 0) ret.back() += k; @@ -10,6 +16,6 @@ vector convert_base(T x, T b) { t *= b / k; } if (ret.empty()) ret.emplace_back(0); - reverse(begin(ret), end(ret)); + std::reverse(ret.begin(), ret.end()); return ret; } diff --git a/math/number-theory/divisor.hpp b/math/number-theory/divisor.hpp index a9125085a..d8181414e 100644 --- a/math/number-theory/divisor.hpp +++ b/math/number-theory/divisor.hpp @@ -1,11 +1,17 @@ -vector divisor(int64_t n) { - vector ret; - for (int64_t i = 1; i * i <= n; i++) { +#pragma once + +#include +#include +#include + +std::vector divisor(std::int64_t n) { + std::vector ret; + for (std::int64_t i = 1; i * i <= n; i++) { if (n % i == 0) { ret.push_back(i); if (i * i != n) ret.push_back(n / i); } } - sort(begin(ret), end(ret)); + std::sort(ret.begin(), ret.end()); return ret; } diff --git a/math/number-theory/enumerate-quotients.hpp b/math/number-theory/enumerate-quotients.hpp index eb8b5a47f..eeab2a676 100644 --- a/math/number-theory/enumerate-quotients.hpp +++ b/math/number-theory/enumerate-quotients.hpp @@ -1,7 +1,13 @@ +#pragma once + +#include +#include +#include + template -vector > enumerate_quotients(T n) { +std::vector > enumerate_quotients(T n) { T l = 1; - vector > quotients; + std::vector > quotients; while (l <= n) { T q = n / l; T r = n / q + 1; diff --git a/math/number-theory/euler-phi-table.hpp b/math/number-theory/euler-phi-table.hpp index a2075d4a6..ee9be48b8 100644 --- a/math/number-theory/euler-phi-table.hpp +++ b/math/number-theory/euler-phi-table.hpp @@ -2,8 +2,12 @@ * @brief Euler’s Phi Table(オイラーのφ関数テーブル) * */ -vector euler_phi_table(int n) { - vector euler(n + 1); +#pragma once + +#include + +std::vector euler_phi_table(int n) { + std::vector euler(n + 1); for (int i = 0; i <= n; i++) { euler[i] = i; } diff --git a/math/number-theory/euler-phi.hpp b/math/number-theory/euler-phi.hpp index 471c1d8c9..f86c5ab79 100644 --- a/math/number-theory/euler-phi.hpp +++ b/math/number-theory/euler-phi.hpp @@ -2,6 +2,8 @@ * @brief Euler's Phi(オイラーのφ関数) * */ +#pragma once + template T euler_phi(T n) { T ret = n; diff --git a/math/number-theory/extgcd.hpp b/math/number-theory/extgcd.hpp index a911477d5..f55b17d84 100644 --- a/math/number-theory/extgcd.hpp +++ b/math/number-theory/extgcd.hpp @@ -1,3 +1,5 @@ +#pragma once + template T extgcd(T a, T b, T& x, T& y) { T d = a; diff --git a/math/number-theory/is-prime.hpp b/math/number-theory/is-prime.hpp index 32374fd10..0552a0c12 100644 --- a/math/number-theory/is-prime.hpp +++ b/math/number-theory/is-prime.hpp @@ -1,5 +1,9 @@ -bool is_prime(int64_t x) { - for (int64_t i = 2; i * i <= x; i++) { +#pragma once + +#include + +bool is_prime(std::int64_t x) { + for (std::int64_t i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; diff --git a/math/number-theory/kth-root-integer.hpp b/math/number-theory/kth-root-integer.hpp index 734074dd4..a6eccc065 100644 --- a/math/number-theory/kth-root-integer.hpp +++ b/math/number-theory/kth-root-integer.hpp @@ -1,13 +1,17 @@ -uint64_t kth_root_integer(uint64_t a, int k) { +#pragma once + +#include + +std::uint64_t kth_root_integer(std::uint64_t a, int k) { if (k == 1) return a; auto check = [&](uint32_t x) { - uint64_t mul = 1; + std::uint64_t mul = 1; for (int j = 0; j < k; j++) { if (__builtin_mul_overflow(mul, x, &mul)) return false; } return mul <= a; }; - uint64_t ret = 0; + std::uint64_t ret = 0; for (int i = 31; i >= 0; i--) { if (check(ret | (1u << i))) ret |= 1u << i; } diff --git a/math/number-theory/moebius-mu-table.hpp b/math/number-theory/moebius-mu-table.hpp index 1e782a430..ff3265ab6 100644 --- a/math/number-theory/moebius-mu-table.hpp +++ b/math/number-theory/moebius-mu-table.hpp @@ -1,8 +1,12 @@ /** * @brief Moebius Table(メビウス関数テーブル) */ -vector moebius_table(int n) { - vector mu(n + 1, 1), p(n + 1, 1); +#pragma once + +#include + +std::vector moebius_table(int n) { + std::vector mu(n + 1, 1), p(n + 1, 1); for (int i = 2; i <= n; i++) { if (p[i] == 1) { for (int j = i; j <= n; j += i) p[j] = i; diff --git a/math/number-theory/prime-factor.hpp b/math/number-theory/prime-factor.hpp index c739ef920..381a98f80 100644 --- a/math/number-theory/prime-factor.hpp +++ b/math/number-theory/prime-factor.hpp @@ -1,6 +1,11 @@ -map prime_factor(int64_t n) { - map ret; - for (int64_t i = 2; i * i <= n; i++) { +#pragma once + +#include +#include + +std::map prime_factor(std::int64_t n) { + std::map ret; + for (std::int64_t i = 2; i * i <= n; i++) { while (n % i == 0) { ret[i]++; n /= i; diff --git a/math/rational/rational.hpp b/math/rational/rational.hpp index c4cc8042d..d0a0f9f90 100644 --- a/math/rational/rational.hpp +++ b/math/rational/rational.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + /** * @brief Rational (有理数型) */ @@ -9,7 +14,7 @@ struct Rational { static T gcd(T a, T b) { if (a < 0) a = -a; if (b < 0) b = -b; - return std::__gcd(a, b); + return std::gcd(a, b); } void normalize() { @@ -151,7 +156,7 @@ struct Rational { Rational abs() const { return Rational{num < 0 ? -num : num, den}; } - friend ostream& operator<<(ostream& os, const Rational& r) { + friend std::ostream& operator<<(std::ostream& os, const Rational& r) { return os << r.numerator() << "/" << r.denominator(); } }; diff --git a/other/ceil-div.hpp b/other/ceil-div.hpp index 80a7335e8..3ad493857 100644 --- a/other/ceil-div.hpp +++ b/other/ceil-div.hpp @@ -1,6 +1,10 @@ +#pragma once + +#include + template T ceil_div(T n, T d) { - static_assert(is_integral::value and is_signed::value, + static_assert(std::is_integral::value and std::is_signed::value, "template parameter T must be signed integral type"); return n / d + ((n ^ d) >= 0 && n % d != 0); } diff --git a/other/chrono-timer.hpp b/other/chrono-timer.hpp index 30dcd433f..dcff1cad1 100644 --- a/other/chrono-timer.hpp +++ b/other/chrono-timer.hpp @@ -1,12 +1,17 @@ +#pragma once + +#include + struct ChronoTimer { - chrono::high_resolution_clock::time_point st; + std::chrono::high_resolution_clock::time_point st; ChronoTimer() { reset(); } - void reset() { st = chrono::high_resolution_clock::now(); } + void reset() { st = std::chrono::high_resolution_clock::now(); } - chrono::milliseconds::rep elapsed() { - auto ed = chrono::high_resolution_clock::now(); - return chrono::duration_cast(ed - st).count(); + std::chrono::milliseconds::rep elapsed() { + auto ed = std::chrono::high_resolution_clock::now(); + return std::chrono::duration_cast(ed - st) + .count(); } }; diff --git a/other/compress.hpp b/other/compress.hpp index 88121cc2e..10a5a9558 100644 --- a/other/compress.hpp +++ b/other/compress.hpp @@ -1,34 +1,44 @@ +#pragma once + +#include +#include +#include +#include + template struct Compress { - vector xs; + std::vector xs; Compress() = default; - Compress(const vector& vs) { add(vs); } + Compress(const std::vector& vs) { add(vs); } - Compress(const initializer_list >& vs) { + Compress(const std::initializer_list >& vs) { for (auto& p : vs) add(p); } - void add(const vector& vs) { copy(begin(vs), end(vs), back_inserter(xs)); } + void add(const std::vector& vs) { + std::copy(vs.begin(), vs.end(), std::back_inserter(xs)); + } void add(const T& x) { xs.emplace_back(x); } void build() { - sort(begin(xs), end(xs)); - xs.erase(unique(begin(xs), end(xs)), end(xs)); + std::sort(xs.begin(), xs.end()); + xs.erase(std::unique(xs.begin(), xs.end()), xs.end()); } - vector get(const vector& vs) const { - vector ret; - transform(begin(vs), end(vs), back_inserter(ret), [&](const T& x) { - return lower_bound(begin(xs), end(xs), x) - begin(xs); - }); + std::vector get(const std::vector& vs) const { + std::vector ret; + std::transform( + vs.begin(), vs.end(), std::back_inserter(ret), [&](const T& x) { + return std::lower_bound(xs.begin(), xs.end(), x) - xs.begin(); + }); return ret; } int get(const T& x) const { - return lower_bound(begin(xs), end(xs), x) - begin(xs); + return std::lower_bound(xs.begin(), xs.end(), x) - xs.begin(); } const T& operator[](int k) const { return xs[k]; } diff --git a/other/dice.hpp b/other/dice.hpp index 4cdda0ac1..5ac4cca31 100644 --- a/other/dice.hpp +++ b/other/dice.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + struct Dice { // int x, y; int l, r, f, b, d, u; @@ -58,8 +62,8 @@ struct Dice { l = buff; } - vector makeDice() { - vector ret; + std::vector makeDice() { + std::vector ret; for (int i = 0; i < 6; i++) { Dice d(*this); if (i == 1) d.RollN(); diff --git a/other/floor-div.hpp b/other/floor-div.hpp index 969d8dbab..7fef82c14 100644 --- a/other/floor-div.hpp +++ b/other/floor-div.hpp @@ -1,6 +1,10 @@ +#pragma once + +#include + template T floor_div(T n, T d) { - static_assert(is_integral::value and is_signed::value, + static_assert(std::is_integral::value and std::is_signed::value, "template parameter T must be signed integral type"); return n / d - ((n ^ d) < 0 && n % d != 0); } diff --git a/other/printer.hpp b/other/printer.hpp index 81fab077e..19f170a62 100644 --- a/other/printer.hpp +++ b/other/printer.hpp @@ -1,3 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + /** * @brief Printer(高速出力) */ @@ -27,8 +36,8 @@ struct Printer { private: FILE* fp = nullptr; - static constexpr size_t line_size = 1 << 16; - static constexpr size_t int_digits = 20; + static constexpr std::size_t line_size = 1 << 16; + static constexpr std::size_t int_digits = 20; char line[line_size + 1] = {}; char* st = line; @@ -40,13 +49,13 @@ struct Printer { *st++ = t; } - template ::value, int> = 0> + template ::value, int> = 0> void write_single(T s) { if (st + int_digits >= line + line_size) flush(); - st += to_chars(st, st + int_digits, s).ptr - st; + st += std::to_chars(st, st + int_digits, s).ptr - st; } - void write_single(const string& s) { + void write_single(const std::string& s) { for (auto& c : s) write_single(c); } @@ -55,8 +64,8 @@ struct Printer { } template - void write_single(const vector& s) { - for (size_t i = 0; i < s.size(); i++) { + void write_single(const std::vector& s) { + for (std::size_t i = 0; i < s.size(); i++) { if (i) write_single(' '); write_single(s[i]); } diff --git a/other/random-number-generator.hpp b/other/random-number-generator.hpp index e9dffae3e..3f49b19fa 100644 --- a/other/random-number-generator.hpp +++ b/other/random-number-generator.hpp @@ -1,11 +1,16 @@ +#pragma once + +#include +#include + struct RandomNumberGenerator { - mt19937 mt; + std::mt19937 mt; RandomNumberGenerator() - : mt(chrono::steady_clock::now().time_since_epoch().count()) {} + : mt(std::chrono::steady_clock::now().time_since_epoch().count()) {} int operator()(int a, int b) { // [a, b) - uniform_int_distribution dist(a, b - 1); + std::uniform_int_distribution dist(a, b - 1); return dist(mt); } diff --git a/other/vector-pool.hpp b/other/vector-pool.hpp index 4119f5f21..9a69f40b3 100644 --- a/other/vector-pool.hpp +++ b/other/vector-pool.hpp @@ -1,7 +1,11 @@ +#pragma once + +#include + template struct VectorPool { - vector pool; - vector stock; + std::vector pool; + std::vector stock; int ptr; VectorPool() = default; @@ -14,6 +18,6 @@ struct VectorPool { void clear() { ptr = (int)pool.size(); - for (int i = 0; i < pool.size(); i++) stock[i] = &pool[i]; + for (int i = 0; i < (int)pool.size(); i++) stock[i] = &pool[i]; } }; diff --git a/other/xor-shift.hpp b/other/xor-shift.hpp index 17c1308aa..113d91da0 100644 --- a/other/xor-shift.hpp +++ b/other/xor-shift.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + /** * @brief Xor-Shift * diff --git a/scripts/self-contained-headers.txt b/scripts/self-contained-headers.txt index c6467dc88..0f42b88c5 100644 --- a/scripts/self-contained-headers.txt +++ b/scripts/self-contained-headers.txt @@ -1,14 +1,54 @@ # Headers migrated to direct includes and explicit std:: qualification. dp/cumulative-sum-2d.hpp dp/cumulative-sum.hpp +dp/divide-and-conquer-optimization.hpp dp/edit-distance.hpp dp/knapsack-01-2.hpp dp/knapsack-01.hpp +dp/knapsack-limitations-2.hpp dp/knapsack-limitations.hpp dp/knapsack.hpp dp/largest-rectangle.hpp dp/longest-increasing-subsequence.hpp dp/monotone-minima.hpp +dp/online-offline-dp.hpp +graph/graph-template.hpp +graph/shortest-path/bellman-ford.hpp +graph/shortest-path/bfs.hpp +graph/shortest-path/dijkstra.hpp +graph/shortest-path/grid-bfs.hpp +graph/shortest-path/warshall-floyd.hpp +math/combinatorics/binomial-table.hpp +math/combinatorics/enumeration.hpp +math/combinatorics/montmort.hpp +math/combinatorics/partition-table.hpp +math/combinatorics/sum-of-arithmetic-sequence.hpp +math/combinatorics/sum-of-geometric-sequence.hpp +math/matrix/matrix.hpp +math/matrix/square-matrix.hpp +math/number-theory/convert-base.hpp +math/number-theory/divisor.hpp +math/number-theory/enumerate-quotients.hpp +math/number-theory/euler-phi-table.hpp +math/number-theory/euler-phi.hpp +math/number-theory/extgcd.hpp +math/number-theory/is-prime.hpp +math/number-theory/kth-root-integer.hpp +math/number-theory/moebius-mu-table.hpp +math/number-theory/prime-factor.hpp +math/number-theory/sum-of-floor-of-linear.hpp +math/rational/rational.hpp +other/ceil-div.hpp +other/chrono-timer.hpp +other/compress.hpp +other/dice.hpp +other/floor-div.hpp +other/printer.hpp +other/random-number-generator.hpp +other/vector-pool.hpp +other/xor-shift.hpp +string/manacher.hpp +string/z-algorithm.hpp structure/class/act.hpp structure/class/acted-monoid.hpp structure/class/affine.hpp diff --git a/string/manacher.hpp b/string/manacher.hpp index 93d2c3001..29dbc1bf1 100644 --- a/string/manacher.hpp +++ b/string/manacher.hpp @@ -1,8 +1,14 @@ +#pragma once + +#include +#include +#include + /** * @brief Manacher(最長回文) */ template -vector manacher(S s, bool calc_even = true) { +std::vector manacher(S s, bool calc_even = true) { if (calc_even) { int n = (int)s.size(); assert(n > 0); @@ -16,7 +22,7 @@ vector manacher(S s, bool calc_even = true) { } } int n = (int)s.size(); - vector rad(n); + std::vector rad(n); { int i = 0, j = 0; while (i < n) { diff --git a/string/z-algorithm.hpp b/string/z-algorithm.hpp index 2ee248a95..aa63c7f69 100644 --- a/string/z-algorithm.hpp +++ b/string/z-algorithm.hpp @@ -3,14 +3,19 @@ * @see https://heno239.hatenablog.com/entry/2020/07/07/140651 * */ +#pragma once + +#include +#include + template struct ZAlgorithm { private: - vector s; - vector deleted; - vector > delete_hist; - vector z; - queue cur; + std::vector s; + std::vector deleted; + std::vector > delete_hist; + std::vector z; + std::queue cur; public: ZAlgorithm() : delete_hist{{}} {} @@ -64,8 +69,8 @@ struct ZAlgorithm { int operator[](int k) const { return get(k); } - vector get() { - vector ret(s.size()); + std::vector get() { + std::vector ret(s.size()); for (int i = 0; i < (int)s.size(); i++) { ret[i] = get(i); } diff --git a/structure/class/act.hpp b/structure/class/act.hpp index 0993b8742..bef912991 100644 --- a/structure/class/act.hpp +++ b/structure/class/act.hpp @@ -1,7 +1,5 @@ #pragma once -#pragma once - template struct LambdaAct { using F = F2; diff --git a/structure/class/acted-monoid.hpp b/structure/class/acted-monoid.hpp index c125163ac..a552d7803 100644 --- a/structure/class/acted-monoid.hpp +++ b/structure/class/acted-monoid.hpp @@ -1,7 +1,5 @@ #pragma once -#pragma once - template struct LambdaActedMonoid { diff --git a/structure/class/beats-monoid.hpp b/structure/class/beats-monoid.hpp index 6dd87730c..c32bae775 100644 --- a/structure/class/beats-monoid.hpp +++ b/structure/class/beats-monoid.hpp @@ -1,7 +1,5 @@ #pragma once -#pragma once - template struct LambdaBeatsMonoid { diff --git a/test/unittest/self-contained-header-migration.test.cpp b/test/unittest/self-contained-header-migration.test.cpp index 965868006..fcc1883c9 100644 --- a/test/unittest/self-contained-header-migration.test.cpp +++ b/test/unittest/self-contained-header-migration.test.cpp @@ -1,20 +1,61 @@ // competitive-verifier: STANDALONE #include +#include #include #include #include #include "../../dp/cumulative-sum-2d.hpp" #include "../../dp/cumulative-sum.hpp" +#include "../../dp/divide-and-conquer-optimization.hpp" #include "../../dp/edit-distance.hpp" #include "../../dp/knapsack-01-2.hpp" #include "../../dp/knapsack-01.hpp" +#include "../../dp/knapsack-limitations-2.hpp" #include "../../dp/knapsack-limitations.hpp" #include "../../dp/knapsack.hpp" #include "../../dp/largest-rectangle.hpp" #include "../../dp/longest-increasing-subsequence.hpp" #include "../../dp/monotone-minima.hpp" +#include "../../dp/online-offline-dp.hpp" +#include "../../graph/graph-template.hpp" +#include "../../graph/shortest-path/bellman-ford.hpp" +#include "../../graph/shortest-path/bfs.hpp" +#include "../../graph/shortest-path/dijkstra.hpp" +#include "../../graph/shortest-path/grid-bfs.hpp" +#include "../../graph/shortest-path/warshall-floyd.hpp" +#include "../../math/combinatorics/binomial-table.hpp" +#include "../../math/combinatorics/enumeration.hpp" +#include "../../math/combinatorics/montmort.hpp" +#include "../../math/combinatorics/partition-table.hpp" +#include "../../math/combinatorics/sum-of-arithmetic-sequence.hpp" +#include "../../math/combinatorics/sum-of-geometric-sequence.hpp" +#include "../../math/matrix/matrix.hpp" +#include "../../math/matrix/square-matrix.hpp" +#include "../../math/number-theory/convert-base.hpp" +#include "../../math/number-theory/divisor.hpp" +#include "../../math/number-theory/enumerate-quotients.hpp" +#include "../../math/number-theory/euler-phi-table.hpp" +#include "../../math/number-theory/euler-phi.hpp" +#include "../../math/number-theory/extgcd.hpp" +#include "../../math/number-theory/is-prime.hpp" +#include "../../math/number-theory/kth-root-integer.hpp" +#include "../../math/number-theory/moebius-mu-table.hpp" +#include "../../math/number-theory/prime-factor.hpp" +#include "../../math/number-theory/sum-of-floor-of-linear.hpp" +#include "../../math/rational/rational.hpp" +#include "../../other/ceil-div.hpp" +#include "../../other/chrono-timer.hpp" +#include "../../other/compress.hpp" +#include "../../other/dice.hpp" +#include "../../other/floor-div.hpp" +#include "../../other/printer.hpp" +#include "../../other/random-number-generator.hpp" +#include "../../other/vector-pool.hpp" +#include "../../other/xor-shift.hpp" +#include "../../string/manacher.hpp" +#include "../../string/z-algorithm.hpp" #include "../../structure/class/act.hpp" #include "../../structure/class/acted-monoid.hpp" #include "../../structure/class/affine.hpp" @@ -76,4 +117,42 @@ int main() { SqrtDecomposition decomposition(2); decomposition.build({0, 1}, {4, 5}); assert(decomposition.query(0, 2, 1) == 5); + + assert(ceil_div(-5, 2) == -2 && floor_div(-5, 2) == -3); + Compress compress({3, 1, 3}); + compress.build(); + assert(compress.get(3) == 1 && compress[0] == 1); + assert(divisor(12) == std::vector({1, 2, 3, 4, 6, 12})); + assert(prime_factor(12)[2] == 2 && euler_phi(12) == 4); + assert(euler_phi_table(4) == std::vector({0, 1, 1, 2, 2})); + assert(moebius_table(4) == std::vector({1, 1, -1, -1, 0})); + assert(is_prime(97) && !is_prime(91)); + assert(kth_root_integer(1000, 3) == 10); + assert(convert_base(5, 2) == std::vector({1, 0, 1})); + assert(sum_of_floor_of_linear(4, 3, 1, 0) == 1); + assert(binomial_table(3)[3][1] == 3); + assert(montmort(4)[4] == 9); + assert(partition_table(4, 4)[4][4] == 5); + assert(sum_of_arithmetic_sequence(1, 2, 3) == 9); + assert(Enumeration::C(0, 0) == 1); + + Matrix matrix{{{1, 2}, {3, 4}}}; + assert(matrix.determinant() == -2); + Rational rational(2, 4); + assert(rational.numerator() == 1 && rational.denominator() == 2); + assert(manacher(std::string("aba"), false)[1] == 3); + ZAlgorithm z("ababa"); + assert(z.get()[2] == 3); + + Graph graph(3); + graph.add_edge(0, 1, 1); + graph.add_edge(1, 2, 2); + assert(bfs(graph, 0)[2] == 3); + assert(dijkstra(graph, 0).dist[2] == 3); + assert(bellman_ford(Edges{{0, 1, 1}, {1, 2, 2}}, 3, 0)[2] == 3); + std::vector > distances{{0, 1}, {1, 0}}; + warshall_floyd(distances, 100); + assert(distances[0][1] == 1); + std::vector grid{"S.", ".#"}; + assert(grid_bfs(grid, 'S')[0][1] == 1); } From 0ed813e6191481ab2bab8aa953f04784e4739066 Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 07:05:08 +0000 Subject: [PATCH 03/16] Migrate geometry headers to self-contained includes --- SELF_CONTAINED_HEADER_MIGRATION.md | 6 +- geometry/angle.hpp | 13 ++-- geometry/area.hpp | 2 + geometry/base.hpp | 4 +- geometry/ccw.hpp | 5 +- geometry/circle.hpp | 5 +- geometry/common_area_cp.hpp | 13 ++-- geometry/contains.hpp | 10 ++- geometry/convex_hull.hpp | 9 ++- geometry/convex_polygon_contains.hpp | 4 ++ geometry/convex_polygon_cut.hpp | 2 + geometry/convex_polygon_diameter.hpp | 20 ++++-- geometry/cross_point_cc.hpp | 18 +++-- geometry/cross_point_cl.hpp | 10 ++- geometry/cross_point_cs.hpp | 6 +- geometry/cross_point_ll.hpp | 6 +- geometry/distance_ll.hpp | 2 + geometry/distance_lp.hpp | 6 +- geometry/distance_pp.hpp | 6 +- geometry/distance_sp.hpp | 8 ++- geometry/distance_ss.hpp | 8 ++- geometry/integer/point.hpp | 2 + geometry/is_convex_polygon.hpp | 2 + geometry/is_intersect_cl.hpp | 2 + geometry/is_intersect_cp.hpp | 6 +- geometry/is_intersect_cs.hpp | 8 ++- geometry/is_intersect_ll.hpp | 6 +- geometry/is_intersect_lp.hpp | 6 +- geometry/is_intersect_ls.hpp | 2 + geometry/is_intersect_sp.hpp | 2 + geometry/is_intersect_ss.hpp | 2 + geometry/is_orthogonal.hpp | 2 + geometry/is_parallel.hpp | 2 + geometry/line.hpp | 13 +++- geometry/point.hpp | 32 +++++---- geometry/polygon.hpp | 6 +- geometry/projection.hpp | 4 +- geometry/reflection.hpp | 2 + geometry/segment.hpp | 5 +- scripts/self-contained-headers.txt | 39 +++++++++++ structure/others/decremental-upper-hull.hpp | 43 +++++++----- .../self-contained-header-migration.test.cpp | 65 ++++++++++++++++++- 42 files changed, 331 insertions(+), 83 deletions(-) diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index 07c7e6683..e75c1ebf4 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -22,7 +22,7 @@ | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 80 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 120 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -126,10 +126,12 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null | 2026-08-10 | `math/number-theory/` の11ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `other/` の9ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `string/manacher.hpp`、`string/z-algorithm.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | geometry の基礎・距離・交差判定・多角形関連38ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `geometry/integer/point.hpp`、`structure/others/decremental-upper-hull.hpp` | 標準 include と `std::` 修飾 | ## 次の候補 次の候補として、プロジェクト内ヘッダーへの依存がない `structure/others/generalized-slope-trick.hpp`、`structure/others/permutation-tree.hpp`、 -および geometry の基礎ヘッダー群を検討する。その後も依存関係の葉に近い +および graph・math の基礎ヘッダー群を検討する。その後も依存関係の葉に近い ヘッダーから進め、1コミットの変更範囲を小さく保つ。 diff --git a/geometry/angle.hpp b/geometry/angle.hpp index c8d3789e5..ccb2638d8 100644 --- a/geometry/angle.hpp +++ b/geometry/angle.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "point.hpp" namespace geometry { @@ -8,10 +13,10 @@ Real degree_to_radian(const Real& deg) { return deg * PI / 180.0; } // smaller angle of the a-b-c Real get_smaller_angle(const Point& a, const Point& b, const Point& c) { const Point v(a - b), w(c - b); - auto alpha = atan2(imag(v), real(v)); - auto beta = atan2(imag(w), real(w)); - if (alpha > beta) swap(alpha, beta); + auto alpha = std::atan2(std::imag(v), std::real(v)); + auto beta = std::atan2(std::imag(w), std::real(w)); + if (alpha > beta) std::swap(alpha, beta); Real theta = (beta - alpha); - return min(theta, 2 * PI - theta); + return std::min(theta, 2 * PI - theta); } } // namespace geometry diff --git a/geometry/area.hpp b/geometry/area.hpp index 8c2774a16..c0e0b45fa 100644 --- a/geometry/area.hpp +++ b/geometry/area.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "point.hpp" #include "polygon.hpp" diff --git a/geometry/base.hpp b/geometry/base.hpp index 291d2ea8f..3bfba63f2 100644 --- a/geometry/base.hpp +++ b/geometry/base.hpp @@ -1,9 +1,11 @@ #pragma once +#include + namespace geometry { using Real = double; const Real EPS = 1e-8; -const Real PI = acos(static_cast(-1)); +const Real PI = std::acos(static_cast(-1)); enum { OUT, ON, IN }; diff --git a/geometry/ccw.hpp b/geometry/ccw.hpp index 976729f8e..ac0b4c607 100644 --- a/geometry/ccw.hpp +++ b/geometry/ccw.hpp @@ -1,4 +1,7 @@ #pragma once + +#include + #include "point.hpp" namespace geometry { @@ -13,7 +16,7 @@ int ccw(const Point& a, Point b, Point c) { if (sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE; if (sign(cross(b, c)) == -1) return CLOCKWISE; if (sign(dot(b, c)) == -1) return ONLINE_BACK; - if (norm(b) < norm(c)) return ONLINE_FRONT; + if (std::norm(b) < std::norm(c)) return ONLINE_FRONT; return ON_SEGMENT; } } // namespace geometry diff --git a/geometry/circle.hpp b/geometry/circle.hpp index 179ab8825..201f491de 100644 --- a/geometry/circle.hpp +++ b/geometry/circle.hpp @@ -1,4 +1,7 @@ #pragma once + +#include + #include "point.hpp" namespace geometry { @@ -11,5 +14,5 @@ struct Circle { Circle(const Point& p, const Real& r) : p(p), r(r) {} }; -using Circles = vector; +using Circles = std::vector; } // namespace geometry diff --git a/geometry/common_area_cp.hpp b/geometry/common_area_cp.hpp index 7c4baef4b..0ac4ec9b7 100644 --- a/geometry/common_area_cp.hpp +++ b/geometry/common_area_cp.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "base.hpp" #include "cross_point_cl.hpp" #include "distance_sp.hpp" @@ -11,15 +16,15 @@ Real ca_cp_impl(const Circle& c, const Point& a, const Point& b) { auto va = c.p - a, vb = c.p - b; Real f = cross(va, vb), ret = 0; if (sign(f) == 0) return ret; - if (sign(max(abs(va), abs(vb)) - c.r) <= 0) return f; + if (sign(std::max(std::abs(va), std::abs(vb)) - c.r) <= 0) return f; if (sign(distance_sp(Segment(a, b), c.p) - c.r) >= 0) - return norm(c.r) * arg(vb * conj(va)); + return std::norm(c.r) * std::arg(vb * std::conj(va)); auto tot = cross_point_cl(c, Line(a, b)); if (is_intersect_cs(c, Segment(a, b)) != 2 and dot(a - tot[0], b - tot[0]) < 0) { - swap(tot[0], tot[1]); + std::swap(tot[0], tot[1]); } - tot.emplace(begin(tot), a); + tot.emplace(tot.begin(), a); tot.emplace_back(b); for (int i = 1; i < (int)tot.size(); i++) { ret += ca_cp_impl(c, tot[i - 1], tot[i]); diff --git a/geometry/contains.hpp b/geometry/contains.hpp index 0a006b59b..a0b1f43a9 100644 --- a/geometry/contains.hpp +++ b/geometry/contains.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "base.hpp" #include "point.hpp" #include "polygon.hpp" @@ -8,8 +13,9 @@ int contains(const Polygon& Q, const Point& p) { bool in = false; for (int i = 0; i < Q.size(); i++) { Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p; - if (imag(a) > imag(b)) swap(a, b); - if (sign(imag(a)) <= 0 && 0 < sign(imag(b)) && sign(cross(a, b)) < 0) + if (std::imag(a) > std::imag(b)) std::swap(a, b); + if (sign(std::imag(a)) <= 0 && 0 < sign(std::imag(b)) && + sign(cross(a, b)) < 0) in = !in; if (equals(cross(a, b), 0) && sign(dot(a, b)) <= 0) return ON; } diff --git a/geometry/convex_hull.hpp b/geometry/convex_hull.hpp index 19321912b..755ff72e4 100644 --- a/geometry/convex_hull.hpp +++ b/geometry/convex_hull.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "base.hpp" #include "point.hpp" #include "polygon.hpp" @@ -7,8 +12,8 @@ namespace geometry { Polygon convex_hull(Polygon& p, bool strict = true) { int n = (int)p.size(), k = 0; if (n <= 2) return p; - sort(begin(p), end(p), compare_x); - vector ch(2 * n); + std::sort(p.begin(), p.end(), compare_x); + std::vector ch(2 * n); auto check = [&](int i) { return sign(cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= -1 + strict; }; diff --git a/geometry/convex_polygon_contains.hpp b/geometry/convex_polygon_contains.hpp index 94dcbe976..790ebb76b 100644 --- a/geometry/convex_polygon_contains.hpp +++ b/geometry/convex_polygon_contains.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "base.hpp" #include "point.hpp" #include "polygon.hpp" diff --git a/geometry/convex_polygon_cut.hpp b/geometry/convex_polygon_cut.hpp index 0f0cc8837..186e54784 100644 --- a/geometry/convex_polygon_cut.hpp +++ b/geometry/convex_polygon_cut.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "base.hpp" #include "cross_point_ll.hpp" #include "line.hpp" diff --git a/geometry/convex_polygon_diameter.hpp b/geometry/convex_polygon_diameter.hpp index 095b25a08..65546ff80 100644 --- a/geometry/convex_polygon_diameter.hpp +++ b/geometry/convex_polygon_diameter.hpp @@ -1,16 +1,22 @@ +#pragma once + +#include +#include +#include + #include "point.hpp" #include "polygon.hpp" namespace geometry { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B -pair convex_polygon_diameter(const Polygon& p) { +std::pair convex_polygon_diameter(const Polygon& p) { int N = (int)p.size(); int is = 0, js = 0; for (int i = 1; i < N; i++) { - if (imag(p[i]) > imag(p[is])) is = i; - if (imag(p[i]) < imag(p[js])) js = i; + if (std::imag(p[i]) > std::imag(p[is])) is = i; + if (std::imag(p[i]) < std::imag(p[js])) js = i; } - Real maxdis = norm(p[is] - p[js]); + Real maxdis = std::norm(p[is] - p[js]); int maxi, maxj, i, j; i = maxi = is; @@ -21,12 +27,12 @@ pair convex_polygon_diameter(const Polygon& p) { } else { i = (i + 1) % N; } - if (norm(p[i] - p[j]) > maxdis) { - maxdis = norm(p[i] - p[j]); + if (std::norm(p[i] - p[j]) > maxdis) { + maxdis = std::norm(p[i] - p[j]); maxi = i; maxj = j; } } while (i != is || j != js); - return minmax(maxi, maxj); + return std::minmax(maxi, maxj); } } // namespace geometry diff --git a/geometry/cross_point_cc.hpp b/geometry/cross_point_cc.hpp index a9a989e5e..20d478e2e 100644 --- a/geometry/cross_point_cc.hpp +++ b/geometry/cross_point_cc.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "base.hpp" #include "circle.hpp" #include "point.hpp" @@ -5,13 +9,15 @@ namespace geometry { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E Points cross_point_cc(const Circle& c1, const Circle& c2) { - Real d = abs(c1.p - c2.p), r = c1.r + c2.r; + Real d = std::abs(c1.p - c2.p), r = c1.r + c2.r; if (sign(d - r) > 0 or sign(d + c1.r - c2.r) < 0) return {}; - Real a = acos((norm(c1.r) - norm(c2.r) + norm(d)) / (2 * c1.r * d)); - Real t = arg(c2.p - c1.p); - Point p = c1.p + polar(c1.r, t + a); - Point q = c1.p + polar(c1.r, t - a); - if (equals(real(p), real(q)) && equals(imag(p), imag(q))) return {p}; + Real a = std::acos((std::norm(c1.r) - std::norm(c2.r) + std::norm(d)) / + (2 * c1.r * d)); + Real t = std::arg(c2.p - c1.p); + Point p = c1.p + std::polar(c1.r, t + a); + Point q = c1.p + std::polar(c1.r, t - a); + if (equals(std::real(p), std::real(q)) && equals(std::imag(p), std::imag(q))) + return {p}; return {p, q}; } } // namespace geometry diff --git a/geometry/cross_point_cl.hpp b/geometry/cross_point_cl.hpp index 9e6660b4c..65b0d4ec6 100644 --- a/geometry/cross_point_cl.hpp +++ b/geometry/cross_point_cl.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "base.hpp" #include "circle.hpp" #include "line.hpp" @@ -8,9 +12,9 @@ namespace geometry { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D Points cross_point_cl(const Circle& c, const Line& l) { Point pr = projection(l, c.p); - if (equals(abs(pr - c.p), c.r)) return {pr}; - Point e = (l.b - l.a) / abs(l.b - l.a); - auto k = sqrt(norm(c.r) - norm(pr - c.p)); + if (equals(std::abs(pr - c.p), c.r)) return {pr}; + Point e = (l.b - l.a) / std::abs(l.b - l.a); + auto k = std::sqrt(std::norm(c.r) - std::norm(pr - c.p)); return {pr - e * k, pr + e * k}; } } // namespace geometry diff --git a/geometry/cross_point_cs.hpp b/geometry/cross_point_cs.hpp index be0b44fa4..4184e8b8d 100644 --- a/geometry/cross_point_cs.hpp +++ b/geometry/cross_point_cs.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "circle.hpp" #include "cross_point_cl.hpp" #include "is_intersect_cs.hpp" @@ -10,7 +14,7 @@ Points cross_point_cs(const Circle& c, const Segment& s) { if (num == 0) return {}; if (num == 2) return cross_point_cl(c, s); auto ret = cross_point_cl(c, s); - if (dot(s.a - ret[0], s.b - ret[0]) > 0) swap(ret[0], ret[1]); + if (dot(s.a - ret[0], s.b - ret[0]) > 0) std::swap(ret[0], ret[1]); return {ret[0]}; } } // namespace geometry diff --git a/geometry/cross_point_ll.hpp b/geometry/cross_point_ll.hpp index 7777bf42e..2e50543e2 100644 --- a/geometry/cross_point_ll.hpp +++ b/geometry/cross_point_ll.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "base.hpp" #include "line.hpp" @@ -5,7 +9,7 @@ namespace geometry { Point cross_point_ll(const Line& l, const Line& m) { Real A = cross(l.b - l.a, m.b - m.a); Real B = cross(l.b - l.a, l.b - m.a); - if (equals(abs(A), 0) && equals(abs(B), 0)) return m.a; + if (equals(std::abs(A), 0) && equals(std::abs(B), 0)) return m.a; return m.a + (m.b - m.a) * B / A; } } // namespace geometry diff --git a/geometry/distance_ll.hpp b/geometry/distance_ll.hpp index 422f50df2..f4628559a 100644 --- a/geometry/distance_ll.hpp +++ b/geometry/distance_ll.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "distance_lp.hpp" #include "is_intersect_ll.hpp" #include "line.hpp" diff --git a/geometry/distance_lp.hpp b/geometry/distance_lp.hpp index 39cd098e5..c15e8ab03 100644 --- a/geometry/distance_lp.hpp +++ b/geometry/distance_lp.hpp @@ -1,8 +1,12 @@ +#pragma once + +#include + #include "line.hpp" #include "projection.hpp" namespace geometry { Real distance_lp(const Line& l, const Point& p) { - return abs(p - projection(l, p)); + return std::abs(p - projection(l, p)); } } // namespace geometry diff --git a/geometry/distance_pp.hpp b/geometry/distance_pp.hpp index be81c8d01..43893125d 100644 --- a/geometry/distance_pp.hpp +++ b/geometry/distance_pp.hpp @@ -1,5 +1,9 @@ +#pragma once + +#include + #include "point.hpp" namespace geometry { -Real distance(const Point& a, const Point& b) { return abs(a - b); } +Real distance(const Point& a, const Point& b) { return std::abs(a - b); } } // namespace geometry diff --git a/geometry/distance_sp.hpp b/geometry/distance_sp.hpp index 6abc5adc3..c56d1b93b 100644 --- a/geometry/distance_sp.hpp +++ b/geometry/distance_sp.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "is_intersect_sp.hpp" #include "point.hpp" #include "projection.hpp" @@ -6,7 +10,7 @@ namespace geometry { Real distance_sp(const Segment& s, const Point& p) { Point r = projection(s, p); - if (is_intersect_sp(s, r)) return abs(r - p); - return min(abs(s.a - p), abs(s.b - p)); + if (is_intersect_sp(s, r)) return std::abs(r - p); + return std::min(std::abs(s.a - p), std::abs(s.b - p)); } } // namespace geometry diff --git a/geometry/distance_ss.hpp b/geometry/distance_ss.hpp index 0621b5bdd..dc28e4e5e 100644 --- a/geometry/distance_ss.hpp +++ b/geometry/distance_ss.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "distance_sp.hpp" #include "is_intersect_ss.hpp" #include "segment.hpp" @@ -6,7 +10,7 @@ namespace geometry { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D Real distance_ss(const Segment& a, const Segment& b) { if (is_intersect_ss(a, b)) return 0; - return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), - distance_sp(b, a.b)}); + return std::min({distance_sp(a, b.a), distance_sp(a, b.b), + distance_sp(b, a.a), distance_sp(b, a.b)}); } } // namespace geometry diff --git a/geometry/integer/point.hpp b/geometry/integer/point.hpp index fcef93fc7..57f5b57fc 100644 --- a/geometry/integer/point.hpp +++ b/geometry/integer/point.hpp @@ -1,3 +1,5 @@ +#pragma once + template struct Point { T x, y; diff --git a/geometry/is_convex_polygon.hpp b/geometry/is_convex_polygon.hpp index 6d8b2c633..4397990a6 100644 --- a/geometry/is_convex_polygon.hpp +++ b/geometry/is_convex_polygon.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "ccw.hpp" #include "point.hpp" #include "polygon.hpp" diff --git a/geometry/is_intersect_cl.hpp b/geometry/is_intersect_cl.hpp index ff6d4ba61..906600e20 100644 --- a/geometry/is_intersect_cl.hpp +++ b/geometry/is_intersect_cl.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "base.hpp" #include "circle.hpp" #include "distance_lp.hpp" diff --git a/geometry/is_intersect_cp.hpp b/geometry/is_intersect_cp.hpp index 4c6d8176e..23518d75c 100644 --- a/geometry/is_intersect_cp.hpp +++ b/geometry/is_intersect_cp.hpp @@ -1,9 +1,13 @@ +#pragma once + +#include + #include "base.hpp" #include "circle.hpp" #include "point.hpp" namespace geometry { bool is_intersect_cp(const Circle& c, const Point& p) { - return equals(abs(p - c.p) - c.r, 0); + return equals(std::abs(p - c.p) - c.r, 0); } } // namespace geometry diff --git a/geometry/is_intersect_cs.hpp b/geometry/is_intersect_cs.hpp index a277a296a..55294e040 100644 --- a/geometry/is_intersect_cs.hpp +++ b/geometry/is_intersect_cs.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "base.hpp" #include "circle.hpp" #include "point.hpp" @@ -7,8 +11,8 @@ namespace geometry { int is_intersect_cs(const Circle& c, const Segment& l) { Point h = projection(l, c.p); - if (sign(norm(h - c.p) - norm(c.r)) > 0) return 0; - auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b); + if (sign(std::norm(h - c.p) - std::norm(c.r)) > 0) return 0; + auto d1 = std::abs(c.p - l.a), d2 = std::abs(c.p - l.b); if (sign(c.r - d1) >= 0 && sign(c.r - d2) >= 0) return 0; if (sign(c.r - d1) < 0 && sign(d2 - c.r) > 0 || sign(d1 - c.r) > 0 && sign(c.r - d2) < 0) diff --git a/geometry/is_intersect_ll.hpp b/geometry/is_intersect_ll.hpp index 2607bbb22..6b5b0f59b 100644 --- a/geometry/is_intersect_ll.hpp +++ b/geometry/is_intersect_ll.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "is_parallel.hpp" #include "line.hpp" @@ -5,7 +9,7 @@ namespace geometry { bool is_intersect_ll(const Line& l, const Line& m) { Real A = cross(l.b - l.a, m.b - m.a); Real B = cross(l.b - l.a, l.b - m.a); - if (equals(abs(A), 0) && equals(abs(B), 0)) return true; + if (equals(std::abs(A), 0) && equals(std::abs(B), 0)) return true; return !is_parallel(l, m); } } // namespace geometry diff --git a/geometry/is_intersect_lp.hpp b/geometry/is_intersect_lp.hpp index 183c68bae..a719dc5ad 100644 --- a/geometry/is_intersect_lp.hpp +++ b/geometry/is_intersect_lp.hpp @@ -1,9 +1,13 @@ +#pragma once + +#include + #include "ccw.hpp" #include "line.hpp" #include "point.hpp" namespace geometry { bool is_intersect_lp(const Line& l, const Point& p) { - return abs(ccw(l.a, l.b, p)) != 1; + return std::abs(ccw(l.a, l.b, p)) != 1; } } // namespace geometry diff --git a/geometry/is_intersect_ls.hpp b/geometry/is_intersect_ls.hpp index be0d1ac8e..35b5be679 100644 --- a/geometry/is_intersect_ls.hpp +++ b/geometry/is_intersect_ls.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "base.hpp" #include "line.hpp" #include "point.hpp" diff --git a/geometry/is_intersect_sp.hpp b/geometry/is_intersect_sp.hpp index 2f8b3ed81..e2e045fb0 100644 --- a/geometry/is_intersect_sp.hpp +++ b/geometry/is_intersect_sp.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "ccw.hpp" #include "point.hpp" #include "segment.hpp" diff --git a/geometry/is_intersect_ss.hpp b/geometry/is_intersect_ss.hpp index 868a1b2fd..f76c7630f 100644 --- a/geometry/is_intersect_ss.hpp +++ b/geometry/is_intersect_ss.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "ccw.hpp" #include "point.hpp" #include "segment.hpp" diff --git a/geometry/is_orthogonal.hpp b/geometry/is_orthogonal.hpp index 76b128f94..fbeedb415 100644 --- a/geometry/is_orthogonal.hpp +++ b/geometry/is_orthogonal.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "line.hpp" #include "point.hpp" diff --git a/geometry/is_parallel.hpp b/geometry/is_parallel.hpp index a43b48023..205b9ab88 100644 --- a/geometry/is_parallel.hpp +++ b/geometry/is_parallel.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "line.hpp" #include "point.hpp" diff --git a/geometry/line.hpp b/geometry/line.hpp index e3f6928cf..df10aad51 100644 --- a/geometry/line.hpp +++ b/geometry/line.hpp @@ -1,4 +1,9 @@ #pragma once + +#include +#include +#include + #include "point.hpp" namespace geometry { @@ -26,12 +31,14 @@ struct Line { } } - friend ostream& operator<<(ostream& os, Line& l) { + friend std::ostream& operator<<(std::ostream& os, Line& l) { return os << l.a << " to " << l.b; } - friend istream& operator>>(istream& is, Line& l) { return is >> l.a >> l.b; } + friend std::istream& operator>>(std::istream& is, Line& l) { + return is >> l.a >> l.b; + } }; -using Lines = vector; +using Lines = std::vector; } // namespace geometry diff --git a/geometry/point.hpp b/geometry/point.hpp index ff67aefde..1c5bd2fbc 100644 --- a/geometry/point.hpp +++ b/geometry/point.hpp @@ -1,45 +1,53 @@ #pragma once + +#include +#include +#include +#include + #include "base.hpp" namespace geometry { -using Point = complex; +using Point = std::complex; -istream& operator>>(istream& is, Point& p) { +std::istream& operator>>(std::istream& is, Point& p) { Real a, b; is >> a >> b; p = Point(a, b); return is; } -ostream& operator<<(ostream& os, const Point& p) { - return os << real(p) << " " << imag(p); +std::ostream& operator<<(std::ostream& os, const Point& p) { + return os << std::real(p) << " " << std::imag(p); } Point operator*(const Point& p, const Real& d) { - return Point(real(p) * d, imag(p) * d); + return Point(std::real(p) * d, std::imag(p) * d); } // rotate point p counterclockwise by theta rad Point rotate(Real theta, const Point& p) { - return Point(cos(theta) * real(p) - sin(theta) * imag(p), - sin(theta) * real(p) + cos(theta) * imag(p)); + return Point(std::cos(theta) * std::real(p) - std::sin(theta) * std::imag(p), + std::sin(theta) * std::real(p) + std::cos(theta) * std::imag(p)); } Real cross(const Point& a, const Point& b) { - return real(a) * imag(b) - imag(a) * real(b); + return std::real(a) * std::imag(b) - std::imag(a) * std::real(b); } Real dot(const Point& a, const Point& b) { - return real(a) * real(b) + imag(a) * imag(b); + return std::real(a) * std::real(b) + std::imag(a) * std::imag(b); } bool compare_x(const Point& a, const Point& b) { - return equals(real(a), real(b)) ? imag(a) < imag(b) : real(a) < real(b); + return equals(std::real(a), std::real(b)) ? std::imag(a) < std::imag(b) + : std::real(a) < std::real(b); } bool compare_y(const Point& a, const Point& b) { - return equals(imag(a), imag(b)) ? real(a) < real(b) : imag(a) < imag(b); + return equals(std::imag(a), std::imag(b)) ? std::real(a) < std::real(b) + : std::imag(a) < std::imag(b); } -using Points = vector; +using Points = std::vector; } // namespace geometry diff --git a/geometry/polygon.hpp b/geometry/polygon.hpp index 44254e558..1f9ebe756 100644 --- a/geometry/polygon.hpp +++ b/geometry/polygon.hpp @@ -1,8 +1,10 @@ #pragma once +#include + #include "point.hpp" namespace geometry { -using Polygon = vector; -using Polygons = vector; +using Polygon = std::vector; +using Polygons = std::vector; } // namespace geometry diff --git a/geometry/projection.hpp b/geometry/projection.hpp index b256811c5..7d26c1013 100644 --- a/geometry/projection.hpp +++ b/geometry/projection.hpp @@ -1,12 +1,14 @@ #pragma once +#include + #include "line.hpp" #include "point.hpp" namespace geometry { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A Point projection(const Line& l, const Point& p) { - auto t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b); + auto t = dot(p - l.a, l.a - l.b) / std::norm(l.a - l.b); return l.a + (l.a - l.b) * t; } } // namespace geometry diff --git a/geometry/reflection.hpp b/geometry/reflection.hpp index d513ce92e..689440e63 100644 --- a/geometry/reflection.hpp +++ b/geometry/reflection.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "line.hpp" #include "point.hpp" #include "projection.hpp" diff --git a/geometry/segment.hpp b/geometry/segment.hpp index 200b9cf9e..94c5fad23 100644 --- a/geometry/segment.hpp +++ b/geometry/segment.hpp @@ -1,4 +1,7 @@ #pragma once + +#include + #include "line.hpp" namespace geometry { @@ -8,5 +11,5 @@ struct Segment : Line { using Line::Line; }; -using Segments = vector; +using Segments = std::vector; } // namespace geometry diff --git a/scripts/self-contained-headers.txt b/scripts/self-contained-headers.txt index 0f42b88c5..51b5cdcfb 100644 --- a/scripts/self-contained-headers.txt +++ b/scripts/self-contained-headers.txt @@ -12,6 +12,44 @@ dp/largest-rectangle.hpp dp/longest-increasing-subsequence.hpp dp/monotone-minima.hpp dp/online-offline-dp.hpp +geometry/angle.hpp +geometry/area.hpp +geometry/base.hpp +geometry/ccw.hpp +geometry/circle.hpp +geometry/common_area_cp.hpp +geometry/contains.hpp +geometry/convex_hull.hpp +geometry/convex_polygon_contains.hpp +geometry/convex_polygon_cut.hpp +geometry/convex_polygon_diameter.hpp +geometry/cross_point_cc.hpp +geometry/cross_point_cl.hpp +geometry/cross_point_cs.hpp +geometry/cross_point_ll.hpp +geometry/distance_ll.hpp +geometry/distance_lp.hpp +geometry/distance_pp.hpp +geometry/distance_sp.hpp +geometry/distance_ss.hpp +geometry/integer/point.hpp +geometry/is_convex_polygon.hpp +geometry/is_intersect_cl.hpp +geometry/is_intersect_cp.hpp +geometry/is_intersect_cs.hpp +geometry/is_intersect_ll.hpp +geometry/is_intersect_lp.hpp +geometry/is_intersect_ls.hpp +geometry/is_intersect_sp.hpp +geometry/is_intersect_ss.hpp +geometry/is_orthogonal.hpp +geometry/is_parallel.hpp +geometry/line.hpp +geometry/point.hpp +geometry/polygon.hpp +geometry/projection.hpp +geometry/reflection.hpp +geometry/segment.hpp graph/graph-template.hpp graph/shortest-path/bellman-ford.hpp graph/shortest-path/bfs.hpp @@ -62,6 +100,7 @@ structure/heap/persistent-leftist-heap.hpp structure/heap/skew-heap.hpp structure/others/abstract-binary-indexed-tree.hpp structure/others/binary-indexed-tree.hpp +structure/others/decremental-upper-hull.hpp structure/others/deque-operate-aggregation.hpp structure/others/disjoint-sparse-table.hpp structure/others/linear-rmq.hpp diff --git a/structure/others/decremental-upper-hull.hpp b/structure/others/decremental-upper-hull.hpp index 6f4d5f7b5..351d9e777 100644 --- a/structure/others/decremental-upper-hull.hpp +++ b/structure/others/decremental-upper-hull.hpp @@ -1,7 +1,16 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + template struct DecrementalUpperHull { private: - using Point = pair; + using Point = std::pair; static constexpr T2 cross(const Point& a, const Point& b) { return T2(a.first) * b.second - T2(a.second) * b.first; @@ -32,12 +41,12 @@ struct DecrementalUpperHull { int lch, rch; }; - size_t n, sz; - vector alive; - vector seg; - vector links; + std::size_t n, sz; + std::vector alive; + std::vector seg; + std::vector links; - pair find_bridge(LP l, LP r) const { + std::pair find_bridge(LP l, LP r) const { while (l->next or r->next) { if (not r->next or (l->next and ccw(sub(l->next->p, l->p), sub(r->next->p, r->p)) <= 0)) { @@ -57,7 +66,7 @@ struct DecrementalUpperHull { return {l, r}; } - pair find_bridge_rev(LP l, LP r) const { + std::pair find_bridge_rev(LP l, LP r) const { while (r->prev or l->prev) { if (not l->prev or (r->prev and ccw(sub(r->prev->p, r->p), sub(l->prev->p, l->p)) >= 0)) { @@ -80,9 +89,9 @@ struct DecrementalUpperHull { template void fix_chain(int u, LP l, LP r) { if (rev) - tie(r, l) = find_bridge_rev(l, r); + std::tie(r, l) = find_bridge_rev(l, r); else - tie(l, r) = find_bridge(l, r); + std::tie(l, r) = find_bridge(l, r); Node& l_node = seg[seg[u].lch]; Node& r_node = seg[seg[u].rch]; @@ -163,10 +172,10 @@ struct DecrementalUpperHull { } } - size_t build(size_t& k, int l, int r) { + std::size_t build(std::size_t& k, int l, int r) { if (r - l == 1) return l + n; int m = (l + r) / 2; - size_t res = k++; + std::size_t res = k++; seg[res].lch = build(k, l, m); seg[res].rch = build(k, m, r); fix_chain(res, seg[seg[res].lch].chain, seg[seg[res].rch].chain); @@ -174,9 +183,9 @@ struct DecrementalUpperHull { } public: - explicit DecrementalUpperHull(const vector& ps) + explicit DecrementalUpperHull(const std::vector& ps) : n(ps.size()), seg(2 * n), sz(n), alive(n) { - assert(is_sorted(ps.begin(), ps.end())); + assert(std::is_sorted(ps.begin(), ps.end())); links.reserve(n); for (int k = 0; k < n; ++k) { links.emplace_back(Link{ps[k], nullptr, nullptr, k}); @@ -185,11 +194,11 @@ struct DecrementalUpperHull { seg[k + n] = {&links[k], &links[k], nullptr, -1, -1}; } if (ps.size() == 1) seg[0] = seg[1]; - size_t u = 0; + std::size_t u = 0; build(u, 0, n); } - size_t size() const { return sz; } + std::size_t size() const { return sz; } bool empty() const { return sz == 0; } @@ -206,8 +215,8 @@ struct DecrementalUpperHull { return true; } - vector get_hull() const { - vector ret; + std::vector get_hull() const { + std::vector ret; for (LP u = seg[0].chain; u; u = u->next) { ret.push_back(u->id); } diff --git a/test/unittest/self-contained-header-migration.test.cpp b/test/unittest/self-contained-header-migration.test.cpp index fcc1883c9..19d3f82f3 100644 --- a/test/unittest/self-contained-header-migration.test.cpp +++ b/test/unittest/self-contained-header-migration.test.cpp @@ -19,6 +19,44 @@ #include "../../dp/longest-increasing-subsequence.hpp" #include "../../dp/monotone-minima.hpp" #include "../../dp/online-offline-dp.hpp" +#include "../../geometry/angle.hpp" +#include "../../geometry/area.hpp" +#include "../../geometry/base.hpp" +#include "../../geometry/ccw.hpp" +#include "../../geometry/circle.hpp" +#include "../../geometry/common_area_cp.hpp" +#include "../../geometry/contains.hpp" +#include "../../geometry/convex_hull.hpp" +#include "../../geometry/convex_polygon_contains.hpp" +#include "../../geometry/convex_polygon_cut.hpp" +#include "../../geometry/convex_polygon_diameter.hpp" +#include "../../geometry/cross_point_cc.hpp" +#include "../../geometry/cross_point_cl.hpp" +#include "../../geometry/cross_point_cs.hpp" +#include "../../geometry/cross_point_ll.hpp" +#include "../../geometry/distance_ll.hpp" +#include "../../geometry/distance_lp.hpp" +#include "../../geometry/distance_pp.hpp" +#include "../../geometry/distance_sp.hpp" +#include "../../geometry/distance_ss.hpp" +#include "../../geometry/integer/point.hpp" +#include "../../geometry/is_convex_polygon.hpp" +#include "../../geometry/is_intersect_cl.hpp" +#include "../../geometry/is_intersect_cp.hpp" +#include "../../geometry/is_intersect_cs.hpp" +#include "../../geometry/is_intersect_ll.hpp" +#include "../../geometry/is_intersect_lp.hpp" +#include "../../geometry/is_intersect_ls.hpp" +#include "../../geometry/is_intersect_sp.hpp" +#include "../../geometry/is_intersect_ss.hpp" +#include "../../geometry/is_orthogonal.hpp" +#include "../../geometry/is_parallel.hpp" +#include "../../geometry/line.hpp" +#include "../../geometry/point.hpp" +#include "../../geometry/polygon.hpp" +#include "../../geometry/projection.hpp" +#include "../../geometry/reflection.hpp" +#include "../../geometry/segment.hpp" #include "../../graph/graph-template.hpp" #include "../../graph/shortest-path/bellman-ford.hpp" #include "../../graph/shortest-path/bfs.hpp" @@ -63,6 +101,7 @@ #include "../../structure/class/monoid.hpp" #include "../../structure/class/range-add-range-min.hpp" #include "../../structure/class/range-chmin-chmax-add-range-sum.hpp" +#include "../../structure/others/decremental-upper-hull.hpp" #include "../../structure/others/slope-trick.hpp" #include "../../structure/others/sqrt-decomposition.hpp" #include "../../structure/others/union-rectangle.hpp" @@ -150,9 +189,33 @@ int main() { assert(bfs(graph, 0)[2] == 3); assert(dijkstra(graph, 0).dist[2] == 3); assert(bellman_ford(Edges{{0, 1, 1}, {1, 2, 2}}, 3, 0)[2] == 3); - std::vector > distances{{0, 1}, {1, 0}}; + std::vector> distances{{0, 1}, {1, 0}}; warshall_floyd(distances, 100); assert(distances[0][1] == 1); std::vector grid{"S.", ".#"}; assert(grid_bfs(grid, 'S')[0][1] == 1); + + using geometry::Circle; + using geometry::Line; + using geometry::Point; + using geometry::Polygon; + using geometry::Segment; + Point a(0, 0), b(3, 4); + assert(geometry::distance(a, b) == 5); + assert(geometry::equals(geometry::cross(a, b), 0)); + Line line(a, b); + Segment segment(Point(0, 4), Point(3, 0)); + assert(geometry::is_intersect_ls(line, segment)); + assert(geometry::is_orthogonal(Line(Point(0, 0), Point(1, 0)), + Line(Point(0, 0), Point(0, 1)))); + Circle circle(Point(0, 0), 1); + assert(geometry::is_intersect_cp(circle, Point(1, 0))); + Polygon polygon{Point(0, 0), Point(2, 0), Point(0, 2)}; + assert(geometry::area(polygon) == 2); + assert(geometry::contains(polygon, Point(1, 1)) == geometry::ON); + std::vector hull = geometry::convex_hull(polygon); + assert(hull.size() == 3); + DecrementalUpperHull upper_hull( + std::vector>{{0, 0}, {1, 1}, {2, 0}}); + assert(upper_hull.size() == 3); } From 4b2d57716f1977dbf1607896b244282fa88ec2d9 Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 07:09:20 +0000 Subject: [PATCH 04/16] Complete geometry header migration batch --- SELF_CONTAINED_HEADER_MIGRATION.md | 2 +- geometry/convex-layers.hpp | 22 +++++++++++++------ scripts/self-contained-headers.txt | 1 + .../self-contained-header-migration.test.cpp | 3 +++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index e75c1ebf4..962d8e08e 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -127,7 +127,7 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null | 2026-08-10 | `other/` の9ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `string/manacher.hpp`、`string/z-algorithm.hpp` | 標準 include と `std::` 修飾 | | 2026-08-10 | geometry の基礎・距離・交差判定・多角形関連38ヘッダー | 標準 include と `std::` 修飾 | -| 2026-08-10 | `geometry/integer/point.hpp`、`structure/others/decremental-upper-hull.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `geometry/integer/point.hpp`、`geometry/convex-layers.hpp`、`structure/others/decremental-upper-hull.hpp` | 標準 include と `std::` 修飾 | ## 次の候補 diff --git a/geometry/convex-layers.hpp b/geometry/convex-layers.hpp index 5723c253b..14ae78d52 100644 --- a/geometry/convex-layers.hpp +++ b/geometry/convex-layers.hpp @@ -1,22 +1,30 @@ +#pragma once + +#include +#include +#include +#include + #include "../structure/others/decremental-upper-hull.hpp" template -vector convex_layers(const vector >& ps) { +std::vector convex_layers(const std::vector >& ps) { int n = (int)ps.size(); - vector ord(n); - iota(ord.begin(), ord.end(), 0); - sort(ord.begin(), ord.end(), [&](int a, int b) { return ps[a] < ps[b]; }); - vector > us(n); + std::vector ord(n); + std::iota(ord.begin(), ord.end(), 0); + std::sort(ord.begin(), ord.end(), + [&](int a, int b) { return ps[a] < ps[b]; }); + std::vector > us(n); for (int i = 0; i < n; i++) { us[i] = ps[ord[i]]; } DecrementalUpperHull upper_hull(us); - vector > ds(n); + std::vector > ds(n); for (int i = 0; i < n; i++) { ds[i] = {-us[n - i - 1].first, -us[n - i - 1].second}; } DecrementalUpperHull lower_hull(ds); - vector convex_hull, res(n, -1); + std::vector convex_hull, res(n, -1); convex_hull.reserve(n); for (int layer = 1; not lower_hull.empty(); layer++) { for (auto& p : upper_hull.get_hull()) { diff --git a/scripts/self-contained-headers.txt b/scripts/self-contained-headers.txt index 51b5cdcfb..165270723 100644 --- a/scripts/self-contained-headers.txt +++ b/scripts/self-contained-headers.txt @@ -19,6 +19,7 @@ geometry/ccw.hpp geometry/circle.hpp geometry/common_area_cp.hpp geometry/contains.hpp +geometry/convex-layers.hpp geometry/convex_hull.hpp geometry/convex_polygon_contains.hpp geometry/convex_polygon_cut.hpp diff --git a/test/unittest/self-contained-header-migration.test.cpp b/test/unittest/self-contained-header-migration.test.cpp index 19d3f82f3..fabd4cadb 100644 --- a/test/unittest/self-contained-header-migration.test.cpp +++ b/test/unittest/self-contained-header-migration.test.cpp @@ -26,6 +26,7 @@ #include "../../geometry/circle.hpp" #include "../../geometry/common_area_cp.hpp" #include "../../geometry/contains.hpp" +#include "../../geometry/convex-layers.hpp" #include "../../geometry/convex_hull.hpp" #include "../../geometry/convex_polygon_contains.hpp" #include "../../geometry/convex_polygon_cut.hpp" @@ -218,4 +219,6 @@ int main() { DecrementalUpperHull upper_hull( std::vector>{{0, 0}, {1, 1}, {2, 0}}); assert(upper_hull.size() == 3); + assert((convex_layers({{0, 0}, {1, 0}, {0, 1}}) == + std::vector({1, 1, 1}))); } From 560e558474c1be8264a51e5bc19810624a42d801 Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 07:26:44 +0000 Subject: [PATCH 05/16] Migrate 40 more headers to self-contained includes --- SELF_CONTAINED_HEADER_MIGRATION.md | 4 +- math/combinatorics/arbitrary-mod-int.hpp | 20 ++-- math/combinatorics/bell-number.hpp | 9 +- .../binomial-prefix-sum-query.hpp | 2 + math/combinatorics/binomial.hpp | 14 ++- .../count-bounded-increasing-sequences.hpp | 96 ++++++++++--------- math/combinatorics/factorial.hpp | 27 ++++-- math/combinatorics/lagrange-polynomial-2.hpp | 9 +- math/combinatorics/lagrange-polynomial-3.hpp | 24 +++-- math/combinatorics/lagrange-polynomial.hpp | 15 ++- math/combinatorics/mod-log.hpp | 22 +++-- math/combinatorics/mod-pow.hpp | 6 +- math/combinatorics/mod-sqrt.hpp | 4 + math/combinatorics/mod-tetration.hpp | 2 + math/combinatorics/modint-2-61m1.hpp | 11 ++- math/combinatorics/montgomery-mod-int.hpp | 19 ++-- math/combinatorics/sample-point-shift.hpp | 13 ++- math/combinatorics/stirling-number-second.hpp | 2 + math/combinatorics/vectorize-mod-int.hpp | 12 ++- math/fft/arbitrary-mod-convolution-long.hpp | 22 +++-- math/fft/arbitrary-mod-convolution.hpp | 21 ++-- math/fft/bitwise-and-convolution.hpp | 7 +- math/fft/bitwise-or-convolution.hpp | 7 +- math/fft/bitwise-xor-convolution.hpp | 7 +- math/fft/fast-fourier-transform.hpp | 29 ++++-- math/fft/fast-walsh-hadamard-transform.hpp | 7 +- ...r-theoretic-transform-friendly-mod-int.hpp | 41 ++++---- math/fft/number-theoretic-transform.hpp | 16 +++- math/fft/subset-convolution.hpp | 35 ++++--- math/fft/subset-zeta-moebius-transform.hpp | 9 +- .../superset-zeta-moebius-transform-simd.hpp | 4 + math/fft/superset-zeta-moebius-transform.hpp | 9 +- math/number-theory/enumerate-primes.hpp | 11 ++- .../fast-prime-factorization.hpp | 59 +++++++----- math/number-theory/prime-count.hpp | 33 ++++--- math/number-theory/prime-table.hpp | 8 +- other/offline-rmq.hpp | 15 ++- other/static-range-frequency.hpp | 28 +++--- scripts/self-contained-headers.txt | 40 ++++++++ structure/class/point-add-rectangle-sum.hpp | 2 + structure/class/point-set-range-composite.hpp | 2 + structure/class/range-affine-range-sum.hpp | 6 +- .../self-contained-header-migration.test.cpp | 59 ++++++++++++ 43 files changed, 551 insertions(+), 237 deletions(-) diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index 962d8e08e..cc1cbf081 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -22,7 +22,7 @@ | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 120 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 160 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -128,6 +128,8 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null | 2026-08-10 | `string/manacher.hpp`、`string/z-algorithm.hpp` | 標準 include と `std::` 修飾 | | 2026-08-10 | geometry の基礎・距離・交差判定・多角形関連38ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `geometry/integer/point.hpp`、`geometry/convex-layers.hpp`、`structure/others/decremental-upper-hull.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `math/combinatorics/` の18ヘッダー、`math/fft/` の13ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `math/number-theory/` の4ヘッダー、`structure/class/` の3ヘッダー、`other/` の2ヘッダー | 標準 include と `std::` 修飾 | ## 次の候補 diff --git a/math/combinatorics/arbitrary-mod-int.hpp b/math/combinatorics/arbitrary-mod-int.hpp index d0f6677f2..f3a47b441 100644 --- a/math/combinatorics/arbitrary-mod-int.hpp +++ b/math/combinatorics/arbitrary-mod-int.hpp @@ -1,9 +1,15 @@ +#pragma once + +#include +#include +#include + struct ArbitraryModInt { int x; ArbitraryModInt() : x(0) {} - ArbitraryModInt(int64_t y) + ArbitraryModInt(std::int64_t y) : x(y >= 0 ? y % get_mod() : (get_mod() - (-y) % get_mod()) % get_mod()) { } @@ -63,13 +69,13 @@ struct ArbitraryModInt { int a = x, b = get_mod(), u = 1, v = 0, t; while (b > 0) { t = a / b; - swap(a -= t * b, b); - swap(u -= t * v, v); + std::swap(a -= t * b, b); + std::swap(u -= t * v, v); } return ArbitraryModInt(u); } - ArbitraryModInt pow(int64_t n) const { + ArbitraryModInt pow(std::int64_t n) const { ArbitraryModInt ret(1), mul(x); while (n > 0) { if (n & 1) ret *= mul; @@ -79,12 +85,12 @@ struct ArbitraryModInt { return ret; } - friend ostream& operator<<(ostream& os, const ArbitraryModInt& p) { + friend std::ostream& operator<<(std::ostream& os, const ArbitraryModInt& p) { return os << p.x; } - friend istream& operator>>(istream& is, ArbitraryModInt& a) { - int64_t t; + friend std::istream& operator>>(std::istream& is, ArbitraryModInt& a) { + std::int64_t t; is >> t; a = ArbitraryModInt(t); return (is); diff --git a/math/combinatorics/bell-number.hpp b/math/combinatorics/bell-number.hpp index 435cacd08..66e458828 100644 --- a/math/combinatorics/bell-number.hpp +++ b/math/combinatorics/bell-number.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "enumeration.hpp" /** @@ -7,10 +12,10 @@ template T bell_number(int n, int k) { if (n == 0) return 1; - k = min(k, n); + k = std::min(k, n); Enumeration uku(k); T ret = 0; - vector pref(k + 1); + std::vector pref(k + 1); pref[0] = 1; for (int i = 1; i <= k; i++) { if (i & 1) diff --git a/math/combinatorics/binomial-prefix-sum-query.hpp b/math/combinatorics/binomial-prefix-sum-query.hpp index 5479d1400..73657fe3c 100644 --- a/math/combinatorics/binomial-prefix-sum-query.hpp +++ b/math/combinatorics/binomial-prefix-sum-query.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "enumeration.hpp" /** diff --git a/math/combinatorics/binomial.hpp b/math/combinatorics/binomial.hpp index 21ee29214..cb4e4b16f 100644 --- a/math/combinatorics/binomial.hpp +++ b/math/combinatorics/binomial.hpp @@ -1,20 +1,26 @@ +#pragma once + +#include +#include +#include + /** * @brief Binomial(二項係数) * */ template -T binomial(int64_t N, int64_t K) { +T binomial(std::int64_t N, std::int64_t K) { if (K < 0 || N < K) return 0; - static vector invs; + static std::vector invs; if (invs.size() < K + 1) { - int pre_sz = max(1, (int)invs.size()); + int pre_sz = std::max(1, (int)invs.size()); invs.resize(K + 1); for (int i = pre_sz; i <= K; i++) { invs[i] = T(1) / i; } } T ret = 1; - for (int64_t i = 1; i <= K; ++i) { + for (std::int64_t i = 1; i <= K; ++i) { ret *= N; N--; ret *= invs[i]; diff --git a/math/combinatorics/count-bounded-increasing-sequences.hpp b/math/combinatorics/count-bounded-increasing-sequences.hpp index c2f8717f8..c504851fc 100644 --- a/math/combinatorics/count-bounded-increasing-sequences.hpp +++ b/math/combinatorics/count-bounded-increasing-sequences.hpp @@ -1,5 +1,11 @@ #pragma once +#include +#include +#include +#include +#include + #include "../fft/number-theoretic-transform-friendly-mod-int.hpp" #include "enumeration.hpp" @@ -7,22 +13,22 @@ * @brief Count Bounded Increasing Sequences */ template -Mint count_bounded_increasing_sequences(const vector& lower_bounds, - const vector& upper_bounds) { +Mint count_bounded_increasing_sequences(const std::vector& lower_bounds, + const std::vector& upper_bounds) { using NTT = NumberTheoreticTransformFriendlyModInt; assert(lower_bounds.size() == upper_bounds.size()); const int original_n = static_cast(upper_bounds.size()); if (original_n == 0) return Mint(1); - vector lower(lower_bounds), upper(upper_bounds); + std::vector lower(lower_bounds), upper(upper_bounds); for (int i = 0; i < original_n; i++) { assert(lower[i] >= 0); assert(upper[i] >= 0); - if (i > 0) lower[i] = max(lower[i], lower[i - 1]); + if (i > 0) lower[i] = std::max(lower[i], lower[i - 1]); } for (int i = original_n - 1; i-- > 0;) { - upper[i] = min(upper[i], upper[i + 1]); + upper[i] = std::min(upper[i], upper[i + 1]); } for (int i = 0; i < original_n; i++) { if (lower[i] >= upper[i]) return Mint(0); @@ -32,7 +38,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, // Shift the lower boundary one column to the right and translate by L[0]. const int base = lower[0]; const int n = original_n + 1; - vector lower_boundary(n), upper_boundary(n); + std::vector lower_boundary(n), upper_boundary(n); lower_boundary[0] = 0; for (int i = 0; i < original_n; i++) { lower_boundary[i + 1] = lower[i] - base; @@ -42,22 +48,23 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, upper_boundary[original_n] = upper.back() - base + 1; const int max_factorial = n + upper_boundary.back() + 5; - assert(static_cast(max_factorial) < Mint::mod()); + assert(static_cast(max_factorial) < Mint::mod()); Enumeration enumeration(max_factorial); // Compute only the first `limit` coefficients. - auto convolution_prefix = [&](vector f, vector g, int limit) { + auto convolution_prefix = [&](std::vector f, std::vector g, + int limit) { assert(limit >= 0); - if (limit == 0) return vector(); + if (limit == 0) return std::vector(); assert(!f.empty() && !g.empty()); if (static_cast(f.size()) > limit) f.resize(limit); if (static_cast(g.size()) > limit) g.resize(limit); - if (min(f.size(), g.size()) <= 32) { - vector result(limit); + if (std::min(f.size(), g.size()) <= 32) { + std::vector result(limit); for (int i = 0; i < static_cast(f.size()); i++) { if (f[i] == Mint(0)) continue; - const int m = min(static_cast(g.size()), limit - i); + const int m = std::min(static_cast(g.size()), limit - i); for (int j = 0; j < m; j++) result[i + j] += f[i] * g[j]; } return result; @@ -68,28 +75,30 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, return result; }; - auto propagate_rectangle = [&](const vector& left_edge, - const vector& bottom_edge) { + auto propagate_rectangle = [&](const std::vector& left_edge, + const std::vector& bottom_edge) { const int height = static_cast(left_edge.size()); const int width = static_cast(bottom_edge.size()); assert(width > 0); if (height == 0) { - return make_pair(bottom_edge, vector()); + return std::make_pair(bottom_edge, std::vector()); } - vector top_edge(width), right_edge(height); - const bool has_left = any_of(left_edge.begin(), left_edge.end(), - [](const Mint& x) { return x != Mint(0); }); - const bool has_bottom = any_of(bottom_edge.begin(), bottom_edge.end(), - [](const Mint& x) { return x != Mint(0); }); + std::vector top_edge(width), right_edge(height); + const bool has_left = + std::any_of(left_edge.begin(), left_edge.end(), + [](const Mint& x) { return x != Mint(0); }); + const bool has_bottom = + std::any_of(bottom_edge.begin(), bottom_edge.end(), + [](const Mint& x) { return x != Mint(0); }); // Left -> top and bottom -> right are middle products with the same // factorial kernel. A cyclic convolution of length >= height + width - 1 // computes the required middle coefficients without wraparound. if (has_left || has_bottom) { - if (min(height, width) <= 32) { + if (std::min(height, width) <= 32) { if (has_left) { - vector scaled(height); + std::vector scaled(height); for (int k = 0; k < height; k++) { scaled[k] = left_edge[height - 1 - k] * enumeration.finv(k); } @@ -102,7 +111,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, } } if (has_bottom) { - vector scaled(width); + std::vector scaled(width); for (int k = 0; k < width; k++) { scaled[k] = bottom_edge[width - 1 - k] * enumeration.finv(k); } @@ -118,7 +127,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, int size = 1; while (size < height + width - 1) size <<= 1; - vector kernel(size); + std::vector kernel(size); for (int i = 0; i < height + width - 1; i++) { kernel[i] = enumeration.fact(i); } @@ -128,10 +137,10 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, const Mint inv_size = Mint(1) / Mint(size); for (auto& x : kernel) x *= inv_size; - auto apply_middle_product = [&](const vector& input, - vector& output) { + auto apply_middle_product = [&](const std::vector& input, + std::vector& output) { const int input_size = static_cast(input.size()); - vector f(size); + std::vector f(size); f[0] = input[input_size - 1]; for (int k = 1; k < input_size; k++) { f[size - k] = input[input_size - 1 - k] * enumeration.finv(k); @@ -151,7 +160,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, // Bottom -> top. if (has_bottom) { - vector kernel(width); + std::vector kernel(width); for (int i = 0; i < width; i++) { kernel[i] = enumeration.fact(height - 1 + i) * enumeration.finv(i); } @@ -162,7 +171,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, // Left -> right. if (has_left) { - vector kernel(height); + std::vector kernel(height); for (int i = 0; i < height; i++) { kernel[i] = enumeration.fact(width - 1 + i) * enumeration.finv(i); } @@ -171,18 +180,19 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, for (int i = 0; i < height; i++) right_edge[i] += coefficient * f[i]; } - return make_pair(top_edge, right_edge); + return std::make_pair(top_edge, right_edge); }; // Solve a one-sided staircase. `heights` must be nondecreasing, and // `start[i]` is an additive source at the i-th bottom-edge vertex. - auto solve_one_sided = [&](const vector& heights, - const vector& start) -> vector { + auto solve_one_sided = + [&](const std::vector& heights, + const std::vector& start) -> std::vector { const int size = static_cast(heights.size()); assert(size > 0); assert(static_cast(start.size()) == size); - vector bounds(size); + std::vector bounds(size); for (int i = 0; i < size; i++) { assert(heights[i] >= 0); if (i > 0) assert(heights[i - 1] <= heights[i]); @@ -190,23 +200,23 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, } auto rec = [&](auto& self, int l, int r, int bottom, - const vector& bottom_edge) -> vector { + const std::vector& bottom_edge) -> std::vector { assert(static_cast(bottom_edge.size()) == r - l); if (l + 1 == r) { - return vector(bounds[l] - bottom, bottom_edge[0]); + return std::vector(bounds[l] - bottom, bottom_edge[0]); } const int mid = (l + r) >> 1; const int height = bounds[mid] - bottom; - auto left_edge = self( - self, l, mid, bottom, - vector(bottom_edge.begin(), bottom_edge.begin() + mid - l)); + auto left_edge = self(self, l, mid, bottom, + std::vector(bottom_edge.begin(), + bottom_edge.begin() + mid - l)); left_edge.resize(height); auto [top_edge, right_edge] = propagate_rectangle( left_edge, - vector(bottom_edge.begin() + mid - l, bottom_edge.end())); + std::vector(bottom_edge.begin() + mid - l, bottom_edge.end())); right_edge.resize(bounds[r - 1] - bottom); auto upper_right = self(self, mid, r, bounds[mid], top_edge); @@ -222,13 +232,13 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, // Decompose the corridor into alternating horizontal and vertical // one-sided staircases. Vertical pieces are transposed. const int distance = static_cast( - upper_bound(lower_boundary.begin(), lower_boundary.end(), 0) - + std::upper_bound(lower_boundary.begin(), lower_boundary.end(), 0) - lower_boundary.begin()); int px = 0, py = 0; int qx = distance - 1, qy = 0; if (qx == 0) qy = upper_boundary[0]; - vector current(abs(qx - px) + abs(qy - py) + 1); + std::vector current(std::abs(qx - px) + std::abs(qy - py) + 1); current[0] = Mint(1); bool first_piece = true; @@ -242,7 +252,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, first_piece = false; if (py == qy) { - vector heights(qx - px + 1); + std::vector heights(qx - px + 1); for (int i = 0; i <= qx - px; i++) { heights[i] = upper_boundary[px + i] - py; } @@ -255,7 +265,7 @@ Mint count_bounded_increasing_sequences(const vector& lower_bounds, // monotonically over this vertical segment. int x = qx + 1; const int base_x = x; - vector heights(qy - py + 1); + std::vector heights(qy - py + 1); for (int i = 0; i <= qy - py; i++) { const int y = py + i; while (x < n && lower_boundary[x] <= y) ++x; diff --git a/math/combinatorics/factorial.hpp b/math/combinatorics/factorial.hpp index 1ecedc6be..ed9add84c 100644 --- a/math/combinatorics/factorial.hpp +++ b/math/combinatorics/factorial.hpp @@ -1,25 +1,34 @@ +#pragma once + +#include +#include +#include +#include + #include "sample-point-shift.hpp" /** * @brief Factorial(階乗) */ template -Mint factorial(int64_t n, const F& multiply) { +Mint factorial(std::int64_t n, const F& multiply) { if (n <= 1) return 1; if (n >= Mint::mod()) return 0; - int64_t v = 1; + std::int64_t v = 1; while (v * v < n) v *= 2; Mint iv = Mint(1) / v; - vector G{1, v + 1}; - for (int64_t d = 1; d != v; d <<= 1) { - vector G1 = sample_point_shift(G, Mint(d) * iv, multiply); - vector G2 = sample_point_shift(G, Mint(d * v + v) * iv, multiply); - vector G3 = sample_point_shift(G, Mint(d * v + d + v) * iv, multiply); + std::vector G{1, v + 1}; + for (std::int64_t d = 1; d != v; d <<= 1) { + std::vector G1 = sample_point_shift(G, Mint(d) * iv, multiply); + std::vector G2 = + sample_point_shift(G, Mint(d * v + v) * iv, multiply); + std::vector G3 = + sample_point_shift(G, Mint(d * v + d + v) * iv, multiply); for (int i = 0; i <= d; i++) G[i] *= G1[i], G2[i] *= G3[i]; - copy(begin(G2), end(G2) - 1, back_inserter(G)); + std::copy(std::begin(G2), std::end(G2) - 1, std::back_inserter(G)); } Mint res = 1; - int64_t i = 0; + std::int64_t i = 0; while (i + v <= n) res *= G[i / v], i += v; while (i < n) res *= ++i; return res; diff --git a/math/combinatorics/lagrange-polynomial-2.hpp b/math/combinatorics/lagrange-polynomial-2.hpp index 499cb42ff..27a0aa0a3 100644 --- a/math/combinatorics/lagrange-polynomial-2.hpp +++ b/math/combinatorics/lagrange-polynomial-2.hpp @@ -1,11 +1,16 @@ +#pragma once + +#include + /** * @brief Lagrange Polynomial(多項式補間, 係数) */ template -vector lagrange_polynomial(const vector& x, const vector& y) { +std::vector lagrange_polynomial(const std::vector& x, + const std::vector& y) { int k = (int)x.size() - 1; - vector f(k + 1), dp(k + 2); + std::vector f(k + 1), dp(k + 2); dp[0] = 1; for (int j = 0; j <= k; j++) { for (int l = k + 1; l > 0; l--) { diff --git a/math/combinatorics/lagrange-polynomial-3.hpp b/math/combinatorics/lagrange-polynomial-3.hpp index b2b898def..0ebf37d8a 100644 --- a/math/combinatorics/lagrange-polynomial-3.hpp +++ b/math/combinatorics/lagrange-polynomial-3.hpp @@ -1,15 +1,23 @@ +#pragma once + +#include +#include +#include +#include + /** * @brief Lagrange Polynomial(多項式補間, 値) */ template -vector lagrange_polynomial(const vector& y, int64_t T, const int& m, - const F& multiply) { +std::vector lagrange_polynomial(const std::vector& y, + std::int64_t T, const int& m, + const F& multiply) { int k = (int)y.size() - 1; T %= Mint::mod(); if (T <= k) { - vector ret(m); + std::vector ret(m); int ptr = 0; - for (int64_t i = T; i <= k and ptr < m; i++) { + for (std::int64_t i = T; i <= k and ptr < m; i++) { ret[ptr++] = y[i]; } if (k + 1 < T + m) { @@ -23,11 +31,11 @@ vector lagrange_polynomial(const vector& y, int64_t T, const int& m, if (T + m > Mint::mod()) { auto pref = lagrange_polynomial(y, T, Mint::mod() - T, multiply); auto suf = lagrange_polynomial(y, 0, m - pref.size(), multiply); - copy(begin(suf), end(suf), back_inserter(pref)); + std::copy(std::begin(suf), std::end(suf), std::back_inserter(pref)); return pref; } - vector finv(k + 1, 1), d(k + 1); + std::vector finv(k + 1, 1), d(k + 1); for (int i = 2; i <= k; i++) finv[k] *= i; finv[k] = Mint(1) / finv[k]; for (int i = k; i >= 1; i--) finv[i - 1] = finv[i] * i; @@ -36,14 +44,14 @@ vector lagrange_polynomial(const vector& y, int64_t T, const int& m, if ((k - i) & 1) d[i] = -d[i]; } - vector h(m + k); + std::vector h(m + k); for (int i = 0; i < m + k; i++) { h[i] = Mint(1) / (T - k + i); } auto dh = multiply(d, h); - vector ret(m); + std::vector ret(m); Mint cur = T; for (int i = 1; i <= k; i++) cur *= T - i; for (int i = 0; i < m; i++) { diff --git a/math/combinatorics/lagrange-polynomial.hpp b/math/combinatorics/lagrange-polynomial.hpp index 7ab463be1..0df5c8b94 100644 --- a/math/combinatorics/lagrange-polynomial.hpp +++ b/math/combinatorics/lagrange-polynomial.hpp @@ -1,17 +1,24 @@ +#pragma once + +#include +#include + +#include "enumeration.hpp" + /** * @brief Lagrange Polynomial(多項式補間, 値) */ template -T lagrange_polynomial(const vector& y, int64_t t) { +T lagrange_polynomial(const std::vector& y, std::int64_t t) { int N = y.size() - 1; - Combination comb(N); + Enumeration comb(N); if (t <= N) return y[t]; T ret(0); - vector dp(N + 1, 1), pd(N + 1, 1); + std::vector dp(N + 1, 1), pd(N + 1, 1); for (int i = 0; i < N; i++) dp[i + 1] = dp[i] * (t - i); for (int i = N; i > 0; i--) pd[i - 1] = pd[i] * (t - i); for (int i = 0; i <= N; i++) { - T tmp = y[i] * dp[i] * pd[i] * comb.rfact(i) * comb.rfact(N - i); + T tmp = y[i] * dp[i] * pd[i] * comb.finv(i) * comb.finv(N - i); if ((N - i) & 1) ret -= tmp; else diff --git a/math/combinatorics/mod-log.hpp b/math/combinatorics/mod-log.hpp index 1fb71270c..ab889ead1 100644 --- a/math/combinatorics/mod-log.hpp +++ b/math/combinatorics/mod-log.hpp @@ -1,14 +1,20 @@ +#pragma once + +#include +#include +#include + /** * @brief Mod Log(離散対数問題) * */ -int64_t mod_log(int64_t a, int64_t b, int64_t p) { - int64_t g = 1; +std::int64_t mod_log(std::int64_t a, std::int64_t b, std::int64_t p) { + std::int64_t g = 1; for (int64_t i = p; i; i /= 2) (g *= a) %= p; - g = __gcd(g, p); + g = std::gcd(g, p); - int64_t t = 1, c = 0; + std::int64_t t = 1, c = 0; for (; t % g; c++) { if (t == b) return c; (t *= a) %= p; @@ -18,16 +24,16 @@ int64_t mod_log(int64_t a, int64_t b, int64_t p) { t /= g; b /= g; - int64_t n = p / g, h = 0, gs = 1; + std::int64_t n = p / g, h = 0, gs = 1; for (; h * h < n; h++) (gs *= a) %= n; - unordered_map bs; - for (int64_t s = 0, e = b; s < h; bs[e] = ++s) { + std::unordered_map bs; + for (std::int64_t s = 0, e = b; s < h; bs[e] = ++s) { (e *= a) %= n; } - for (int64_t s = 0, e = t; s < n;) { + for (std::int64_t s = 0, e = t; s < n;) { (e *= gs) %= n; s += h; if (bs.count(e)) return c + s - bs[e]; diff --git a/math/combinatorics/mod-pow.hpp b/math/combinatorics/mod-pow.hpp index d4d9fd777..c1a30198a 100644 --- a/math/combinatorics/mod-pow.hpp +++ b/math/combinatorics/mod-pow.hpp @@ -1,9 +1,13 @@ +#pragma once + +#include + /** * @brief Mod Pow(べき乗) * */ template -T mod_pow(T x, int64_t n, const T& p) { +T mod_pow(T x, std::int64_t n, const T& p) { T ret = 1; while (n > 0) { if (n & 1) (ret *= x) %= p; diff --git a/math/combinatorics/mod-sqrt.hpp b/math/combinatorics/mod-sqrt.hpp index 699131546..4637f8b3c 100644 --- a/math/combinatorics/mod-sqrt.hpp +++ b/math/combinatorics/mod-sqrt.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include "mod-pow.hpp" + /** * @brief Mod Sqrt */ diff --git a/math/combinatorics/mod-tetration.hpp b/math/combinatorics/mod-tetration.hpp index aaf844a9e..7eed0a761 100644 --- a/math/combinatorics/mod-tetration.hpp +++ b/math/combinatorics/mod-tetration.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "../number-theory/euler-phi.hpp" #include "mod-pow.hpp" diff --git a/math/combinatorics/modint-2-61m1.hpp b/math/combinatorics/modint-2-61m1.hpp index 9d2b31d2b..ebc98f086 100644 --- a/math/combinatorics/modint-2-61m1.hpp +++ b/math/combinatorics/modint-2-61m1.hpp @@ -1,7 +1,12 @@ +#pragma once + +#include +#include + struct ModInt_2_61m1 { private: using mint = ModInt_2_61m1; - using u64 = uint64_t; + using u64 = std::uint64_t; using u128 = __uint128_t; u64 x; @@ -61,11 +66,11 @@ struct ModInt_2_61m1 { mint inv() const { return pow(mod() - 2); } - friend ostream& operator<<(ostream& os, const mint& p) { + friend std::ostream& operator<<(std::ostream& os, const mint& p) { return os << p.val(); } - friend istream& operator>>(istream& is, mint& a) { + friend std::istream& operator>>(std::istream& is, mint& a) { u64 t; is >> t; a = mint(t); diff --git a/math/combinatorics/montgomery-mod-int.hpp b/math/combinatorics/montgomery-mod-int.hpp index 4db821582..23fdd6de0 100644 --- a/math/combinatorics/montgomery-mod-int.hpp +++ b/math/combinatorics/montgomery-mod-int.hpp @@ -1,13 +1,16 @@ #pragma once -template +#include +#include + +template struct MontgomeryModInt { private: using mint = MontgomeryModInt; - using i32 = int32_t; - using i64 = int64_t; - using u32 = uint32_t; - using u64 = uint64_t; + using i32 = std::int32_t; + using i64 = std::int64_t; + using u32 = std::uint32_t; + using u64 = std::uint64_t; static constexpr u32 get_r() { u32 ret = mod_; @@ -90,11 +93,11 @@ struct MontgomeryModInt { mint inv() const { return pow(mod() - 2); } - friend ostream& operator<<(ostream& os, const mint& p) { + friend std::ostream& operator<<(std::ostream& os, const mint& p) { return os << p.val(); } - friend istream& operator>>(istream& is, mint& a) { + friend std::istream& operator>>(std::istream& is, mint& a) { i64 t; is >> t; a = mint(t); @@ -104,7 +107,7 @@ struct MontgomeryModInt { static constexpr u32 mod() { return mod_; } }; -template +template using modint = MontgomeryModInt; using modint998244353 = modint<998244353>; using modint1000000007 = modint<1000000007>; diff --git a/math/combinatorics/sample-point-shift.hpp b/math/combinatorics/sample-point-shift.hpp index 6696dfd76..d2d9dad9c 100644 --- a/math/combinatorics/sample-point-shift.hpp +++ b/math/combinatorics/sample-point-shift.hpp @@ -1,14 +1,19 @@ +#pragma once + +#include +#include + #include "enumeration.hpp" /** * @brief Sample Point Shift(標本点シフト) */ template -vector sample_point_shift(const vector& ys, const Mint& m, - const F& multiply) { +std::vector sample_point_shift(const std::vector& ys, const Mint& m, + const F& multiply) { Enumeration comb; int d = (int)ys.size() - 1; - vector f(d + 1), g(d * 2 + 1); + std::vector f(d + 1), g(d * 2 + 1); for (int i = 0; i <= d; i++) { f[i] = ys[i] * comb.finv(i) * comb.finv(d - i); if ((d - i) & 1) f[i] = -f[i]; @@ -25,5 +30,5 @@ vector sample_point_shift(const vector& ys, const Mint& m, h[i + d] *= coef; coef *= (m + i + 1) * g[i]; } - return vector{begin(h) + d, begin(h) + 2 * d + 1}; + return std::vector{std::begin(h) + d, std::begin(h) + 2 * d + 1}; } diff --git a/math/combinatorics/stirling-number-second.hpp b/math/combinatorics/stirling-number-second.hpp index 073e8c7ca..c37920a33 100644 --- a/math/combinatorics/stirling-number-second.hpp +++ b/math/combinatorics/stirling-number-second.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "enumeration.hpp" /** diff --git a/math/combinatorics/vectorize-mod-int.hpp b/math/combinatorics/vectorize-mod-int.hpp index 134516125..bbf59838b 100644 --- a/math/combinatorics/vectorize-mod-int.hpp +++ b/math/combinatorics/vectorize-mod-int.hpp @@ -1,12 +1,16 @@ +#pragma once + #include + +#include #pragma GCC target("avx2") struct alignas(32) VectorizeModInt { using Mints = VectorizeModInt; - using i32 = int32_t; - using i64 = int64_t; - using u32 = uint32_t; - using u64 = uint64_t; + using i32 = std::int32_t; + using i64 = std::int64_t; + using u32 = std::uint32_t; + using u64 = std::uint64_t; static __m256i m0, m1, m2, r1; diff --git a/math/fft/arbitrary-mod-convolution-long.hpp b/math/fft/arbitrary-mod-convolution-long.hpp index 13ae0b53d..9998ced7f 100644 --- a/math/fft/arbitrary-mod-convolution-long.hpp +++ b/math/fft/arbitrary-mod-convolution-long.hpp @@ -1,3 +1,10 @@ +#pragma once + +#include +#include + +#include "fast-fourier-transform.hpp" + template struct ArbitraryModConvolutionLong { using real = FastFourierTransform::real; @@ -5,18 +12,19 @@ struct ArbitraryModConvolutionLong { ArbitraryModConvolutionLong() = default; - vector multiply(const vector& a, const vector& b, int need = -1) { + std::vector multiply(const std::vector& a, const std::vector& b, + int need = -1) { if (need == -1) need = a.size() + b.size() - 1; int nbase = 0; while ((1 << nbase) < need) nbase++; FastFourierTransform::ensure_base(nbase); int sz = 1 << nbase; - vector fa(sz); + std::vector fa(sz); for (int i = 0; i < a.size(); i++) { fa[i] = C(a[i].x & ((1 << 19) - 1), a[i].x >> 19); } fft(fa, sz); - vector fb(sz); + std::vector fb(sz); if (a == b) { fb = fa; } else { @@ -46,13 +54,13 @@ struct ArbitraryModConvolutionLong { } fft(fa, sz); fft(fb, sz); - vector ret(need); + std::vector ret(need); auto mul1 = T(2).pow(19); auto mul2 = T(2).pow(38); for (int i = 0; i < need; i++) { - int64_t aa = llround(fa[i].x); - int64_t bb = llround(fb[i].x); - int64_t cc = llround(fa[i].y); + std::int64_t aa = std::llround(fa[i].x); + std::int64_t bb = std::llround(fb[i].x); + std::int64_t cc = std::llround(fa[i].y); aa = T(aa).x, bb = T(bb).x, cc = T(cc).x; ret[i] = (mul1 * bb) + (mul2 * cc) + aa; } diff --git a/math/fft/arbitrary-mod-convolution.hpp b/math/fft/arbitrary-mod-convolution.hpp index 15c70678e..6143ce190 100644 --- a/math/fft/arbitrary-mod-convolution.hpp +++ b/math/fft/arbitrary-mod-convolution.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "fast-fourier-transform.hpp" /* @@ -10,19 +15,19 @@ struct ArbitraryModConvolution { ArbitraryModConvolution() = default; - static vector multiply(const vector& a, const vector& b, - int need = -1) { + static std::vector multiply(const std::vector& a, + const std::vector& b, int need = -1) { if (need == -1) need = a.size() + b.size() - 1; int nbase = 0; while ((1 << nbase) < need) nbase++; FastFourierTransform::ensure_base(nbase); int sz = 1 << nbase; - vector fa(sz); + std::vector fa(sz); for (int i = 0; i < a.size(); i++) { fa[i] = C(a[i].val() & ((1 << 15) - 1), a[i].val() >> 15); } fft(fa, sz); - vector fb(sz); + std::vector fb(sz); if (a == b) { fb = fa; } else { @@ -52,11 +57,11 @@ struct ArbitraryModConvolution { } fft(fa, sz); fft(fb, sz); - vector ret(need); + std::vector ret(need); for (int i = 0; i < need; i++) { - int64_t aa = llround(fa[i].x); - int64_t bb = llround(fb[i].x); - int64_t cc = llround(fa[i].y); + std::int64_t aa = std::llround(fa[i].x); + std::int64_t bb = std::llround(fb[i].x); + std::int64_t cc = std::llround(fa[i].y); aa = T(aa).val(), bb = T(bb).val(), cc = T(cc).val(); ret[i] = aa + (bb << 15) + (cc << 30); } diff --git a/math/fft/bitwise-and-convolution.hpp b/math/fft/bitwise-and-convolution.hpp index cb371e8cc..0154dc9a0 100644 --- a/math/fft/bitwise-and-convolution.hpp +++ b/math/fft/bitwise-and-convolution.hpp @@ -1,10 +1,15 @@ +#pragma once + +#include +#include + #include "superset-zeta-moebius-transform.hpp" /** * @brief Bitwise And Convolution (Bitwise-AND畳み込み) */ template -vector bitwise_and_convolution(vector f, vector g) { +std::vector bitwise_and_convolution(std::vector f, std::vector g) { const int n = (int)f.size(); assert(f.size() == g.size()); assert((n & (n - 1)) == 0); diff --git a/math/fft/bitwise-or-convolution.hpp b/math/fft/bitwise-or-convolution.hpp index e9800382e..5e0e41b00 100644 --- a/math/fft/bitwise-or-convolution.hpp +++ b/math/fft/bitwise-or-convolution.hpp @@ -1,10 +1,15 @@ +#pragma once + +#include +#include + #include "subset-zeta-moebius-transform.hpp" /** * @brief Bitwise Or Convolution (Bitwise-OR畳み込み) */ template -vector bitwise_or_convolution(vector f, vector g) { +std::vector bitwise_or_convolution(std::vector f, std::vector g) { const int n = (int)f.size(); assert(f.size() == g.size()); assert((n & (n - 1)) == 0); diff --git a/math/fft/bitwise-xor-convolution.hpp b/math/fft/bitwise-xor-convolution.hpp index a96f5ac19..ec0bf7905 100644 --- a/math/fft/bitwise-xor-convolution.hpp +++ b/math/fft/bitwise-xor-convolution.hpp @@ -1,10 +1,15 @@ +#pragma once + +#include +#include + #include "fast-walsh-hadamard-transform.hpp" /** * @brief Bitwise Xor Convolution (Bitwise-XOR畳み込み) */ template -vector bitwise_xor_convolution(vector f, vector g) { +std::vector bitwise_xor_convolution(std::vector f, std::vector g) { const int n = (int)f.size(); assert(f.size() == g.size()); assert((n & (n - 1)) == 0); diff --git a/math/fft/fast-fourier-transform.hpp b/math/fft/fast-fourier-transform.hpp index 55fe61dfd..920517c50 100644 --- a/math/fft/fast-fourier-transform.hpp +++ b/math/fft/fast-fourier-transform.hpp @@ -1,3 +1,11 @@ +#pragma once + +#include +#include +#include +#include +#include + namespace FastFourierTransform { using real = double; @@ -19,10 +27,10 @@ struct C { inline C conj() const { return C(x, -y); } }; -const real PI = acosl(-1); +const real PI = std::acos(-1); int base = 1; -vector rts = {{0, 0}, {1, 0}}; -vector rev = {0, 1}; +std::vector rts = {{0, 0}, {1, 0}}; +std::vector rev = {0, 1}; void ensure_base(int nbase) { if (nbase <= base) return; @@ -36,20 +44,20 @@ void ensure_base(int nbase) { for (int i = 1 << (base - 1); i < (1 << base); i++) { rts[i << 1] = rts[i]; real angle_i = angle * (2 * i + 1 - (1 << base)); - rts[(i << 1) + 1] = C(cos(angle_i), sin(angle_i)); + rts[(i << 1) + 1] = C(std::cos(angle_i), std::sin(angle_i)); } ++base; } } -void fft(vector& a, int n) { +void fft(std::vector& a, int n) { assert((n & (n - 1)) == 0); int zeros = __builtin_ctz(n); ensure_base(zeros); int shift = base - zeros; for (int i = 0; i < n; i++) { if (i < (rev[i] >> shift)) { - swap(a[i], a[rev[i] >> shift]); + std::swap(a[i], a[rev[i] >> shift]); } } for (int k = 1; k < n; k <<= 1) { @@ -63,13 +71,14 @@ void fft(vector& a, int n) { } } -vector multiply(const vector& a, const vector& b) { +std::vector multiply(const std::vector& a, + const std::vector& b) { int need = (int)a.size() + (int)b.size() - 1; int nbase = 1; while ((1 << nbase) < need) nbase++; ensure_base(nbase); int sz = 1 << nbase; - vector fa(sz); + std::vector fa(sz); for (int i = 0; i < sz; i++) { int x = (i < (int)a.size() ? a[i] : 0); int y = (i < (int)b.size() ? b[i] : 0); @@ -89,9 +98,9 @@ vector multiply(const vector& a, const vector& b) { fa[i] = A0 + A1 * s; } fft(fa, sz >> 1); - vector ret(need); + std::vector ret(need); for (int i = 0; i < need; i++) { - ret[i] = llround(i & 1 ? fa[i >> 1].y : fa[i >> 1].x); + ret[i] = std::llround(i & 1 ? fa[i >> 1].y : fa[i >> 1].x); } return ret; } diff --git a/math/fft/fast-walsh-hadamard-transform.hpp b/math/fft/fast-walsh-hadamard-transform.hpp index 6f09c6a95..15f67cf2d 100644 --- a/math/fft/fast-walsh-hadamard-transform.hpp +++ b/math/fft/fast-walsh-hadamard-transform.hpp @@ -1,8 +1,13 @@ +#pragma once + +#include +#include + /** * @brief Fast Walsh Hadamard Transform (高速ウォルシュアダマール変換) */ template -void fast_walsh_hadamard_transform(vector& f, bool inv = false) { +void fast_walsh_hadamard_transform(std::vector& f, bool inv = false) { const int n = (int)f.size(); assert((n & (n - 1)) == 0); for (int i = 1; i < n; i <<= 1) { diff --git a/math/fft/number-theoretic-transform-friendly-mod-int.hpp b/math/fft/number-theoretic-transform-friendly-mod-int.hpp index f5301584e..83c3b3f86 100644 --- a/math/fft/number-theoretic-transform-friendly-mod-int.hpp +++ b/math/fft/number-theoretic-transform-friendly-mod-int.hpp @@ -1,9 +1,14 @@ +#pragma once + +#include +#include + /** * @brief Number Theoretic Transform Friendly ModInt */ template struct NumberTheoreticTransformFriendlyModInt { - static vector roots, iroots, rate2, irate2, rate3, irate3; + static std::vector roots, iroots, rate2, irate2, rate3, irate3; static int max_base; NumberTheoreticTransformFriendlyModInt() = default; @@ -55,7 +60,7 @@ struct NumberTheoreticTransformFriendlyModInt { } } - static void ntt(vector& a) { + static void ntt(std::vector& a) { init(); const int n = (int)a.size(); assert((n & (n - 1)) == 0); @@ -114,7 +119,7 @@ struct NumberTheoreticTransformFriendlyModInt { } } - static void intt(vector& a, bool f = true) { + static void intt(std::vector& a, bool f = true) { init(); const int n = (int)a.size(); assert((n & (n - 1)) == 0); @@ -179,7 +184,7 @@ struct NumberTheoreticTransformFriendlyModInt { /** * @brief Transpose of ntt() */ - static void transposed_ntt(vector& a) { + static void transposed_ntt(std::vector& a) { init(); const int n = (int)a.size(); assert((n & (n - 1)) == 0); @@ -231,7 +236,7 @@ struct NumberTheoreticTransformFriendlyModInt { /** * @brief Transpose of intt() */ - static void transposed_intt(vector& a, bool f = true) { + static void transposed_intt(std::vector& a, bool f = true) { init(); const int n = (int)a.size(); assert((n & (n - 1)) == 0); @@ -285,7 +290,7 @@ struct NumberTheoreticTransformFriendlyModInt { } } - static vector multiply(vector a, vector b) { + static std::vector multiply(std::vector a, std::vector b) { int need = a.size() + b.size() - 1; int nbase = 1; while ((1 << nbase) < need) nbase++; @@ -303,22 +308,22 @@ struct NumberTheoreticTransformFriendlyModInt { }; template -vector NumberTheoreticTransformFriendlyModInt::roots = - vector(); +std::vector NumberTheoreticTransformFriendlyModInt::roots = + std::vector(); template -vector NumberTheoreticTransformFriendlyModInt::iroots = - vector(); +std::vector NumberTheoreticTransformFriendlyModInt::iroots = + std::vector(); template -vector NumberTheoreticTransformFriendlyModInt::rate2 = - vector(); +std::vector NumberTheoreticTransformFriendlyModInt::rate2 = + std::vector(); template -vector NumberTheoreticTransformFriendlyModInt::irate2 = - vector(); +std::vector NumberTheoreticTransformFriendlyModInt::irate2 = + std::vector(); template -vector NumberTheoreticTransformFriendlyModInt::rate3 = - vector(); +std::vector NumberTheoreticTransformFriendlyModInt::rate3 = + std::vector(); template -vector NumberTheoreticTransformFriendlyModInt::irate3 = - vector(); +std::vector NumberTheoreticTransformFriendlyModInt::irate3 = + std::vector(); template int NumberTheoreticTransformFriendlyModInt::max_base = 0; diff --git a/math/fft/number-theoretic-transform.hpp b/math/fft/number-theoretic-transform.hpp index 12ff412d0..0fb5af1e4 100644 --- a/math/fft/number-theoretic-transform.hpp +++ b/math/fft/number-theoretic-transform.hpp @@ -1,6 +1,12 @@ +#pragma once + +#include +#include +#include + template struct NumberTheoreticTransform { - vector rev, rts; + std::vector rev, rts; int base, max_base, root; NumberTheoreticTransform() : base(1), rev{0, 1}, rts{0, 1} { @@ -54,7 +60,7 @@ struct NumberTheoreticTransform { } } - void ntt(vector& a) { + void ntt(std::vector& a) { const int n = (int)a.size(); assert((n & (n - 1)) == 0); int zeros = __builtin_ctz(n); @@ -62,7 +68,7 @@ struct NumberTheoreticTransform { int shift = base - zeros; for (int i = 0; i < n; i++) { if (i < (rev[i] >> shift)) { - swap(a[i], a[rev[i] >> shift]); + std::swap(a[i], a[rev[i] >> shift]); } } for (int k = 1; k < n; k <<= 1) { @@ -76,7 +82,7 @@ struct NumberTheoreticTransform { } } - vector multiply(vector a, vector b) { + std::vector multiply(std::vector a, std::vector b) { int need = a.size() + b.size() - 1; int nbase = 1; while ((1 << nbase) < need) nbase++; @@ -90,7 +96,7 @@ struct NumberTheoreticTransform { for (int i = 0; i < sz; i++) { a[i] = mul(a[i], mul(b[i], inv_sz)); } - reverse(a.begin() + 1, a.end()); + std::reverse(a.begin() + 1, a.end()); ntt(a); a.resize(need); return a; diff --git a/math/fft/subset-convolution.hpp b/math/fft/subset-convolution.hpp index 2930ecb41..4be5a318a 100644 --- a/math/fft/subset-convolution.hpp +++ b/math/fft/subset-convolution.hpp @@ -1,10 +1,18 @@ +#pragma once + +#include +#include +#include +#include +#include + /** * @brief Subset Convolution */ template struct SubsetConvolution { - using fps = array; - static array pop_count; + using fps = std::array; + static std::array pop_count; static constexpr int s = _s; SubsetConvolution() = default; @@ -30,7 +38,7 @@ struct SubsetConvolution { } } - static void zeta_transform(vector& F) { + static void zeta_transform(std::vector& F) { const int n = (int)F.size(); assert((n & (n - 1)) == 0); init(); @@ -43,7 +51,7 @@ struct SubsetConvolution { } } - static void moebius_transform(vector& F) { + static void moebius_transform(std::vector& F) { const int n = (int)F.size(); assert((n & (n - 1)) == 0); init(); @@ -56,28 +64,28 @@ struct SubsetConvolution { } } - static vector lift(const vector& f) { + static std::vector lift(const std::vector& f) { const int n = (int)f.size(); init(); - vector F(n); + std::vector F(n); for (int i = 0; i < n; i++) { - fill(begin(F[i]), end(F[i]), Mint()); + std::fill(F[i].begin(), F[i].end(), Mint()); F[i][pop_count[i]] = f[i]; } return F; } - static vector unlift(const vector& F) { + static std::vector unlift(const std::vector& F) { const int n = (int)F.size(); init(); - vector f(n); + std::vector f(n); for (int i = 0; i < (int)F.size(); i++) { f[i] = F[i][pop_count[i]]; } return f; } - static void prod(vector& F, const vector& G) { + static void prod(std::vector& F, const std::vector& G) { int n = (int)F.size(); int d = __builtin_ctz(n); for (int i = 0; i < n; i++) { @@ -87,11 +95,12 @@ struct SubsetConvolution { h[j + k] += F[i][j] * G[i][k]; } } - F[i] = move(h); + F[i] = std::move(h); } } - static vector multiply(const vector& f, const vector& g) { + static std::vector multiply(const std::vector& f, + const std::vector& g) { auto F = lift(f), G = lift(g); zeta_transform(F); zeta_transform(G); @@ -102,4 +111,4 @@ struct SubsetConvolution { }; template -array SubsetConvolution::pop_count; +std::array SubsetConvolution::pop_count; diff --git a/math/fft/subset-zeta-moebius-transform.hpp b/math/fft/subset-zeta-moebius-transform.hpp index e11d3a9ec..fa118719c 100644 --- a/math/fft/subset-zeta-moebius-transform.hpp +++ b/math/fft/subset-zeta-moebius-transform.hpp @@ -1,8 +1,13 @@ +#pragma once + +#include +#include + /** * @brief Subset Zeta/Moebius Transform (下位集合のゼータ/メビウス変換) */ template -void subset_zeta_transform(vector& f) { +void subset_zeta_transform(std::vector& f) { const int n = (int)f.size(); assert((n & (n - 1)) == 0); for (int i = 1; i < n; i <<= 1) { @@ -15,7 +20,7 @@ void subset_zeta_transform(vector& f) { } template -void subset_moebius_transform(vector& f) { +void subset_moebius_transform(std::vector& f) { const int n = (int)f.size(); assert((n & (n - 1)) == 0); for (int i = 1; i < n; i <<= 1) { diff --git a/math/fft/superset-zeta-moebius-transform-simd.hpp b/math/fft/superset-zeta-moebius-transform-simd.hpp index aa390d4e5..34c1e6863 100644 --- a/math/fft/superset-zeta-moebius-transform-simd.hpp +++ b/math/fft/superset-zeta-moebius-transform-simd.hpp @@ -1,5 +1,9 @@ +#pragma once + #include +#include + /** * @brief Superset Zeta/Moebius Transform SIMD (上位集合のゼータ/メビウス変換, * SIMD) diff --git a/math/fft/superset-zeta-moebius-transform.hpp b/math/fft/superset-zeta-moebius-transform.hpp index 2b78efcc1..f29191c91 100644 --- a/math/fft/superset-zeta-moebius-transform.hpp +++ b/math/fft/superset-zeta-moebius-transform.hpp @@ -1,8 +1,13 @@ +#pragma once + +#include +#include + /** * @brief Superset Zeta/Moebius Transform (上位集合のゼータ/メビウス変換) */ template -void superset_zeta_transform(vector& f) { +void superset_zeta_transform(std::vector& f) { const int n = (int)f.size(); assert((n & (n - 1)) == 0); for (int i = 1; i < n; i <<= 1) { @@ -15,7 +20,7 @@ void superset_zeta_transform(vector& f) { } template -void superset_moebius_transform(vector& f) { +void superset_moebius_transform(std::vector& f) { const int n = (int)f.size(); assert((n & (n - 1)) == 0); for (int i = 1; i < n; i <<= 1) { diff --git a/math/number-theory/enumerate-primes.hpp b/math/number-theory/enumerate-primes.hpp index 60b7c2757..9a1cec97e 100644 --- a/math/number-theory/enumerate-primes.hpp +++ b/math/number-theory/enumerate-primes.hpp @@ -1,10 +1,15 @@ +#pragma once + +#include +#include + #include "prime-table.hpp" -vector enumerate_primes(int n) { +std::vector enumerate_primes(int n) { if (n <= 1) return {}; auto d = prime_table(n); - vector primes; - primes.reserve(count(begin(d), end(d), true)); + std::vector primes; + primes.reserve(std::count(d.begin(), d.end(), true)); for (int i = 0; i < d.size(); i++) { if (d[i]) primes.push_back(i); } diff --git a/math/number-theory/fast-prime-factorization.hpp b/math/number-theory/fast-prime-factorization.hpp index 016fb51c3..fb4a82a03 100644 --- a/math/number-theory/fast-prime-factorization.hpp +++ b/math/number-theory/fast-prime-factorization.hpp @@ -1,3 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + namespace FastPrimeFactorization { template @@ -37,7 +46,7 @@ struct UnsafeMod { return UnsafeMod(*this) *= rhs; } - UnsafeMod pow(uint64_t e) const { + UnsafeMod pow(std::uint64_t e) const { UnsafeMod ret(1); for (UnsafeMod base = *this; e; e >>= 1, base *= base) { if (e & 1) ret *= base; @@ -76,31 +85,31 @@ struct UnsafeMod { using uint128_t = __uint128_t; -using Mod64 = UnsafeMod; +using Mod64 = UnsafeMod; template <> -uint64_t Mod64::mod = 0; +std::uint64_t Mod64::mod = 0; template <> -uint64_t Mod64::inv = 0; +std::uint64_t Mod64::inv = 0; template <> -uint64_t Mod64::r2 = 0; +std::uint64_t Mod64::r2 = 0; -using Mod32 = UnsafeMod; +using Mod32 = UnsafeMod; template <> -uint32_t Mod32::mod = 0; +std::uint32_t Mod32::mod = 0; template <> -uint32_t Mod32::inv = 0; +std::uint32_t Mod32::inv = 0; template <> -uint32_t Mod32::r2 = 0; +std::uint32_t Mod32::r2 = 0; -bool miller_rabin_primality_test_uint64(uint64_t n) { +bool miller_rabin_primality_test_uint64(std::uint64_t n) { Mod64::set_mod(n); - uint64_t d = n - 1; + std::uint64_t d = n - 1; while (d % 2 == 0) d /= 2; Mod64 e{1}, rev{n - 1}; // http://miller-rabin.appspot.com/ < 2^64 - for (uint64_t a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) { + for (std::uint64_t a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) { if (n <= a) break; - uint64_t t = d; + std::uint64_t t = d; Mod64 y = Mod64(a).pow(t); while (t != n - 1 && y != e && y != rev) { y *= y; @@ -111,14 +120,14 @@ bool miller_rabin_primality_test_uint64(uint64_t n) { return true; } -bool miller_rabin_primality_test_uint32(uint32_t n) { +bool miller_rabin_primality_test_uint32(std::uint32_t n) { Mod32::set_mod(n); - uint32_t d = n - 1; + std::uint32_t d = n - 1; while (d % 2 == 0) d /= 2; Mod32 e{1}, rev{n - 1}; - for (uint32_t a : {2, 7, 61}) { + for (std::uint32_t a : {2, 7, 61}) { if (n <= a) break; - uint32_t t = d; + std::uint32_t t = d; Mod32 y = Mod32(a).pow(t); while (t != n - 1 && y != e && y != rev) { y *= y; @@ -129,18 +138,18 @@ bool miller_rabin_primality_test_uint32(uint32_t n) { return true; } -bool is_prime(uint64_t n) { +bool is_prime(std::uint64_t n) { if (n == 2) return true; if (n == 1 || n % 2 == 0) return false; - if (n < uint64_t(1) << 31) return miller_rabin_primality_test_uint32(n); + if (n < std::uint64_t(1) << 31) return miller_rabin_primality_test_uint32(n); return miller_rabin_primality_test_uint64(n); } -uint64_t pollard_rho(uint64_t n) { +std::uint64_t pollard_rho(std::uint64_t n) { if (is_prime(n)) return n; if (n % 2 == 0) return 2; Mod64::set_mod(n); - uint64_t d; + std::uint64_t d; Mod64 one{1}; for (Mod64 c{one};; c += one) { Mod64 x{2}, y{2}; @@ -148,20 +157,20 @@ uint64_t pollard_rho(uint64_t n) { x = x * x + c; y = y * y + c; y = y * y + c; - d = __gcd((x - y).get(), n); + d = std::gcd((x - y).get(), n); } while (d == 1); if (d < n) return d; } assert(0); } -vector prime_factor(uint64_t n) { +std::vector prime_factor(std::uint64_t n) { if (n <= 1) return {}; - uint64_t p = pollard_rho(n); + std::uint64_t p = pollard_rho(n); if (p == n) return {p}; auto l = prime_factor(p); auto r = prime_factor(n / p); - copy(begin(r), end(r), back_inserter(l)); + std::copy(r.begin(), r.end(), std::back_inserter(l)); return l; } }; // namespace FastPrimeFactorization diff --git a/math/number-theory/prime-count.hpp b/math/number-theory/prime-count.hpp index 300ed34ca..605f4b406 100644 --- a/math/number-theory/prime-count.hpp +++ b/math/number-theory/prime-count.hpp @@ -1,35 +1,40 @@ +#pragma once + +#include +#include + #include "kth-root-integer.hpp" #include "prime-table.hpp" /** * @brief Prime Count(素数の個数) */ -template +template struct PrimeCount { private: - int64_t sq; - vector prime; - vector prime_sum, primes; + std::int64_t sq; + std::vector prime; + std::vector prime_sum, primes; - int64_t p2(int64_t x, int64_t y) { + std::int64_t p2(std::int64_t x, std::int64_t y) { if (x < 4) return 0; - int64_t a = pi(y); - int64_t b = pi(kth_root_integer(x, 2)); + std::int64_t a = pi(y); + std::int64_t b = pi(kth_root_integer(x, 2)); if (a >= b) return 0; - int64_t sum = (a - 2) * (a + 1) / 2 - (b - 2) * (b + 1) / 2; - for (int64_t i = a; i < b; i++) sum += pi(x / primes[i]); + std::int64_t sum = (a - 2) * (a + 1) / 2 - (b - 2) * (b + 1) / 2; + for (std::int64_t i = a; i < b; i++) sum += pi(x / primes[i]); return sum; } - int64_t phi(int64_t m, int64_t n) { + std::int64_t phi(std::int64_t m, std::int64_t n) { if (m < 1) return 0; if (n > m) return 1; if (n < 1) return m; if (m <= primes[n - 1] * primes[n - 1]) return pi(m) - n + 1; if (m <= primes[n - 1] * primes[n - 1] * primes[n - 1] && m <= sq) { - int64_t sx = pi(kth_root_integer(m, 2)); - int64_t ans = pi(m) - (sx + n - 2) * (sx - n + 1) / 2; - for (int64_t i = n; i < sx; ++i) ans += pi(m / primes[i]); + std::int64_t sx = pi(kth_root_integer(m, 2)); + std::int64_t ans = pi(m) - (sx + n - 2) * (sx - n + 1) / 2; + for (std::int64_t i = n; i < sx; ++i) ans += pi(m / primes[i]); return ans; } return phi(m, n - 1) - phi(m / primes[n - 1], n - 1); @@ -44,7 +49,7 @@ struct PrimeCount { if (prime[i]) primes.push_back(i); } - int64_t pi(int64_t n) { + std::int64_t pi(std::int64_t n) { if (n <= sq) return prime_sum[n]; int64_t m = kth_root_integer(n, 3); int64_t a = pi(m); diff --git a/math/number-theory/prime-table.hpp b/math/number-theory/prime-table.hpp index 35feb7cd4..4c65ed777 100644 --- a/math/number-theory/prime-table.hpp +++ b/math/number-theory/prime-table.hpp @@ -1,9 +1,13 @@ +#pragma once + +#include + /** * @brief Prime Table(素数テーブル) * */ -vector prime_table(int n) { - vector prime(n + 1, true); +std::vector prime_table(int n) { + std::vector prime(n + 1, true); if (n >= 0) prime[0] = false; if (n >= 1) prime[1] = false; for (int i = 2; i * i <= n; i++) { diff --git a/other/offline-rmq.hpp b/other/offline-rmq.hpp index 1dd189528..99365f194 100644 --- a/other/offline-rmq.hpp +++ b/other/offline-rmq.hpp @@ -1,17 +1,24 @@ +#pragma once + +#include +#include +#include + #include "../structure/union-find/union-find.hpp" /** * @brief Offline RMQ **/ template -vector offline_rmq(vector >& qs, const Comp& comp) { +std::vector offline_rmq(std::vector >& qs, + const Comp& comp) { int n = 0; - for (auto& [l, r] : qs) n = max(n, r); + for (auto& [l, r] : qs) n = std::max(n, r); UnionFind uf(n); - vector st(n), mark(n), ans(qs.size()); + std::vector st(n), mark(n), ans(qs.size()); int top = -1; for (auto& [l, r] : qs) mark[r - 1]++; - vector > q(n); + std::vector > q(n); for (int i = 0; i < n; i++) { q[i].reserve(mark[i]); } diff --git a/other/static-range-frequency.hpp b/other/static-range-frequency.hpp index 8135b4319..ab4a74d6d 100644 --- a/other/static-range-frequency.hpp +++ b/other/static-range-frequency.hpp @@ -1,24 +1,30 @@ +#pragma once + +#include +#include +#include + template struct StaticRangeFrequency { private: - vector vs; - vector > mp; + std::vector vs; + std::vector > mp; public: - explicit StaticRangeFrequency(const vector& xs) : vs{xs} { - sort(vs.begin(), vs.end()); - vs.erase(unique(vs.begin(), vs.end()), vs.end()); + explicit StaticRangeFrequency(const std::vector& xs) : vs{xs} { + std::sort(vs.begin(), vs.end()); + vs.erase(std::unique(vs.begin(), vs.end()), vs.end()); mp.resize(vs.size()); for (int i = 0; i < xs.size(); i++) { - int p = lower_bound(vs.begin(), vs.end(), xs[i]) - vs.begin(); + int p = std::lower_bound(vs.begin(), vs.end(), xs[i]) - vs.begin(); mp[p].emplace_back(i); } } - size_t query(int l, int r, T x) const { - int p = lower_bound(vs.begin(), vs.end(), x) - vs.begin(); - if (p == vs.size() or x != vs[p]) return 0; - l = lower_bound(mp[p].begin(), mp[p].end(), l) - vs.begin(); - r = lower_bound(mp[p].begin(), mp[p].end(), r) - vs.begin(); + std::size_t query(int l, int r, T x) const { + int p = std::lower_bound(vs.begin(), vs.end(), x) - vs.begin(); + if (p == (int)vs.size() or x != vs[p]) return 0; + l = std::lower_bound(mp[p].begin(), mp[p].end(), l) - mp[p].begin(); + r = std::lower_bound(mp[p].begin(), mp[p].end(), r) - mp[p].begin(); return r - l; } }; diff --git a/scripts/self-contained-headers.txt b/scripts/self-contained-headers.txt index 165270723..a6e1745d6 100644 --- a/scripts/self-contained-headers.txt +++ b/scripts/self-contained-headers.txt @@ -57,24 +57,59 @@ graph/shortest-path/bfs.hpp graph/shortest-path/dijkstra.hpp graph/shortest-path/grid-bfs.hpp graph/shortest-path/warshall-floyd.hpp +math/combinatorics/arbitrary-mod-int.hpp +math/combinatorics/bell-number.hpp +math/combinatorics/binomial-prefix-sum-query.hpp math/combinatorics/binomial-table.hpp +math/combinatorics/binomial.hpp +math/combinatorics/count-bounded-increasing-sequences.hpp math/combinatorics/enumeration.hpp +math/combinatorics/factorial.hpp +math/combinatorics/lagrange-polynomial-2.hpp +math/combinatorics/lagrange-polynomial-3.hpp +math/combinatorics/lagrange-polynomial.hpp +math/combinatorics/mod-log.hpp +math/combinatorics/mod-pow.hpp +math/combinatorics/mod-sqrt.hpp +math/combinatorics/mod-tetration.hpp +math/combinatorics/modint-2-61m1.hpp +math/combinatorics/montgomery-mod-int.hpp math/combinatorics/montmort.hpp math/combinatorics/partition-table.hpp +math/combinatorics/sample-point-shift.hpp +math/combinatorics/stirling-number-second.hpp math/combinatorics/sum-of-arithmetic-sequence.hpp math/combinatorics/sum-of-geometric-sequence.hpp +math/combinatorics/vectorize-mod-int.hpp +math/fft/arbitrary-mod-convolution-long.hpp +math/fft/arbitrary-mod-convolution.hpp +math/fft/bitwise-and-convolution.hpp +math/fft/bitwise-or-convolution.hpp +math/fft/bitwise-xor-convolution.hpp +math/fft/fast-fourier-transform.hpp +math/fft/fast-walsh-hadamard-transform.hpp +math/fft/number-theoretic-transform-friendly-mod-int.hpp +math/fft/number-theoretic-transform.hpp +math/fft/subset-convolution.hpp +math/fft/subset-zeta-moebius-transform.hpp +math/fft/superset-zeta-moebius-transform-simd.hpp +math/fft/superset-zeta-moebius-transform.hpp math/matrix/matrix.hpp math/matrix/square-matrix.hpp math/number-theory/convert-base.hpp math/number-theory/divisor.hpp +math/number-theory/enumerate-primes.hpp math/number-theory/enumerate-quotients.hpp math/number-theory/euler-phi-table.hpp math/number-theory/euler-phi.hpp math/number-theory/extgcd.hpp +math/number-theory/fast-prime-factorization.hpp math/number-theory/is-prime.hpp math/number-theory/kth-root-integer.hpp math/number-theory/moebius-mu-table.hpp +math/number-theory/prime-count.hpp math/number-theory/prime-factor.hpp +math/number-theory/prime-table.hpp math/number-theory/sum-of-floor-of-linear.hpp math/rational/rational.hpp other/ceil-div.hpp @@ -82,8 +117,10 @@ other/chrono-timer.hpp other/compress.hpp other/dice.hpp other/floor-div.hpp +other/offline-rmq.hpp other/printer.hpp other/random-number-generator.hpp +other/static-range-frequency.hpp other/vector-pool.hpp other/xor-shift.hpp string/manacher.hpp @@ -93,7 +130,10 @@ structure/class/acted-monoid.hpp structure/class/affine.hpp structure/class/beats-monoid.hpp structure/class/monoid.hpp +structure/class/point-add-rectangle-sum.hpp +structure/class/point-set-range-composite.hpp structure/class/range-add-range-min.hpp +structure/class/range-affine-range-sum.hpp structure/class/range-chmin-chmax-add-range-sum.hpp structure/heap/erasable-heap.hpp structure/heap/leftist-heap.hpp diff --git a/structure/class/point-add-rectangle-sum.hpp b/structure/class/point-add-rectangle-sum.hpp index e1838836f..f235dd30b 100644 --- a/structure/class/point-add-rectangle-sum.hpp +++ b/structure/class/point-add-rectangle-sum.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "../others/binary-indexed-tree.hpp" template diff --git a/structure/class/point-set-range-composite.hpp b/structure/class/point-set-range-composite.hpp index 3e637a772..158cc8b9b 100644 --- a/structure/class/point-set-range-composite.hpp +++ b/structure/class/point-set-range-composite.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "affine.hpp" template diff --git a/structure/class/range-affine-range-sum.hpp b/structure/class/range-affine-range-sum.hpp index 7cd2be542..674148bbf 100644 --- a/structure/class/range-affine-range-sum.hpp +++ b/structure/class/range-affine-range-sum.hpp @@ -1,8 +1,12 @@ +#pragma once + +#include + #include "affine.hpp" template struct RangeAffineRangeSum { - using S = pair; + using S = std::pair; using F = Affine; static constexpr S op(const S& a, const S& b) { return {a.first + b.first, a.second + b.second}; diff --git a/test/unittest/self-contained-header-migration.test.cpp b/test/unittest/self-contained-header-migration.test.cpp index fabd4cadb..85bac8f1d 100644 --- a/test/unittest/self-contained-header-migration.test.cpp +++ b/test/unittest/self-contained-header-migration.test.cpp @@ -65,11 +65,42 @@ #include "../../graph/shortest-path/grid-bfs.hpp" #include "../../graph/shortest-path/warshall-floyd.hpp" #include "../../math/combinatorics/binomial-table.hpp" +#include "../../math/combinatorics/arbitrary-mod-int.hpp" +#include "../../math/combinatorics/bell-number.hpp" +#include "../../math/combinatorics/binomial-prefix-sum-query.hpp" +#include "../../math/combinatorics/binomial.hpp" +#include "../../math/combinatorics/count-bounded-increasing-sequences.hpp" #include "../../math/combinatorics/enumeration.hpp" +#include "../../math/combinatorics/factorial.hpp" +#include "../../math/combinatorics/lagrange-polynomial-2.hpp" +#include "../../math/combinatorics/lagrange-polynomial-3.hpp" +#include "../../math/combinatorics/lagrange-polynomial.hpp" +#include "../../math/combinatorics/mod-log.hpp" +#include "../../math/combinatorics/mod-pow.hpp" +#include "../../math/combinatorics/mod-sqrt.hpp" +#include "../../math/combinatorics/mod-tetration.hpp" +#include "../../math/combinatorics/modint-2-61m1.hpp" +#include "../../math/combinatorics/montgomery-mod-int.hpp" #include "../../math/combinatorics/montmort.hpp" #include "../../math/combinatorics/partition-table.hpp" +#include "../../math/combinatorics/sample-point-shift.hpp" #include "../../math/combinatorics/sum-of-arithmetic-sequence.hpp" #include "../../math/combinatorics/sum-of-geometric-sequence.hpp" +#include "../../math/combinatorics/stirling-number-second.hpp" +#include "../../math/combinatorics/vectorize-mod-int.hpp" +#include "../../math/fft/arbitrary-mod-convolution-long.hpp" +#include "../../math/fft/arbitrary-mod-convolution.hpp" +#include "../../math/fft/bitwise-and-convolution.hpp" +#include "../../math/fft/bitwise-or-convolution.hpp" +#include "../../math/fft/bitwise-xor-convolution.hpp" +#include "../../math/fft/fast-fourier-transform.hpp" +#include "../../math/fft/fast-walsh-hadamard-transform.hpp" +#include "../../math/fft/number-theoretic-transform-friendly-mod-int.hpp" +#include "../../math/fft/number-theoretic-transform.hpp" +#include "../../math/fft/subset-convolution.hpp" +#include "../../math/fft/subset-zeta-moebius-transform.hpp" +#include "../../math/fft/superset-zeta-moebius-transform-simd.hpp" +#include "../../math/fft/superset-zeta-moebius-transform.hpp" #include "../../math/matrix/matrix.hpp" #include "../../math/matrix/square-matrix.hpp" #include "../../math/number-theory/convert-base.hpp" @@ -77,11 +108,15 @@ #include "../../math/number-theory/enumerate-quotients.hpp" #include "../../math/number-theory/euler-phi-table.hpp" #include "../../math/number-theory/euler-phi.hpp" +#include "../../math/number-theory/enumerate-primes.hpp" #include "../../math/number-theory/extgcd.hpp" +#include "../../math/number-theory/fast-prime-factorization.hpp" #include "../../math/number-theory/is-prime.hpp" #include "../../math/number-theory/kth-root-integer.hpp" #include "../../math/number-theory/moebius-mu-table.hpp" #include "../../math/number-theory/prime-factor.hpp" +#include "../../math/number-theory/prime-count.hpp" +#include "../../math/number-theory/prime-table.hpp" #include "../../math/number-theory/sum-of-floor-of-linear.hpp" #include "../../math/rational/rational.hpp" #include "../../other/ceil-div.hpp" @@ -93,6 +128,8 @@ #include "../../other/random-number-generator.hpp" #include "../../other/vector-pool.hpp" #include "../../other/xor-shift.hpp" +#include "../../other/offline-rmq.hpp" +#include "../../other/static-range-frequency.hpp" #include "../../string/manacher.hpp" #include "../../string/z-algorithm.hpp" #include "../../structure/class/act.hpp" @@ -100,8 +137,11 @@ #include "../../structure/class/affine.hpp" #include "../../structure/class/beats-monoid.hpp" #include "../../structure/class/monoid.hpp" +#include "../../structure/class/point-add-rectangle-sum.hpp" +#include "../../structure/class/point-set-range-composite.hpp" #include "../../structure/class/range-add-range-min.hpp" #include "../../structure/class/range-chmin-chmax-add-range-sum.hpp" +#include "../../structure/class/range-affine-range-sum.hpp" #include "../../structure/others/decremental-upper-hull.hpp" #include "../../structure/others/slope-trick.hpp" #include "../../structure/others/sqrt-decomposition.hpp" @@ -175,6 +215,25 @@ int main() { assert(partition_table(4, 4)[4][4] == 5); assert(sum_of_arithmetic_sequence(1, 2, 3) == 9); assert(Enumeration::C(0, 0) == 1); + assert(binomial(5, 2) == 10); + assert(mod_pow(2, 10, 1000) == 24); + assert(mod_sqrt(4, 7) == 2 || mod_sqrt(4, 7) == 5); + assert(mod_log(2, 8, 13) == 3); + assert(mod_tetration(2, 3, 1000) == 16); + assert(prime_table(10)[7] && !prime_table(10)[9]); + assert(enumerate_primes(10) == std::vector({2, 3, 5, 7})); + assert(FastPrimeFactorization::prime_factor(84) == + std::vector({2, 2, 3, 7})); + StaticRangeFrequency frequency({1, 2, 1, 3, 1}); + assert(frequency.query(1, 5, 1) == 2); + + std::vector hadamard{1, 2, 3, 4}; + fast_walsh_hadamard_transform(hadamard); + fast_walsh_hadamard_transform(hadamard, true); + assert(hadamard == std::vector({1, 2, 3, 4})); + assert(bitwise_and_convolution(std::vector{1, 0, 0, 0}, + std::vector{1, 1, 1, 1}) + .size() == 4); Matrix matrix{{{1, 2}, {3, 4}}}; assert(matrix.determinant() == -2); From 3301540972f8e1ef8874a6473d3400e1bc187d4f Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 07:40:27 +0000 Subject: [PATCH 06/16] Migrate graph and query headers to self-contained includes --- SELF_CONTAINED_HEADER_MIGRATION.md | 4 +- graph/mst/boruvka.hpp | 15 ++++-- graph/mst/directed-mst.hpp | 8 +-- graph/mst/kruskal.hpp | 7 ++- graph/mst/manhattan-mst.hpp | 22 +++++--- graph/mst/prim.hpp | 13 +++-- graph/others/cartesian-tree.hpp | 10 ++-- graph/others/chromatic-number.hpp | 16 +++--- graph/others/cycle-detection.hpp | 8 ++- graph/others/dominator-tree.hpp | 22 ++++---- graph/others/enumerate-cliques.hpp | 31 ++++++----- graph/others/enumerate-triangles.hpp | 16 +++--- graph/others/eulerian-trail.hpp | 35 ++++++++----- graph/others/extreme-vertex-set.hpp | 27 +++++++--- graph/others/low-link.hpp | 16 +++--- graph/others/maximum-clique.hpp | 33 +++++++----- graph/others/maximum-independent-set.hpp | 35 +++++++++---- graph/others/minimum-steiner-tree.hpp | 34 +++++++++---- graph/others/namori-graph.hpp | 20 +++++--- graph/others/offline-dag-reachability.hpp | 17 ++++--- graph/others/topological-sort.hpp | 11 ++-- graph/others/tree-decomposition-width-2.hpp | 32 +++++++----- graph/tree/centroid.hpp | 15 ++++-- graph/tree/convert-rooted-tree.hpp | 7 ++- graph/tree/heavy-light-decomposition.hpp | 23 +++++---- graph/tree/rerooting.hpp | 15 ++++-- graph/tree/tree-diameter.hpp | 11 ++-- math/matrix/binary-basis.hpp | 31 +++++++---- other/connected-grid-states.hpp | 29 +++++++---- other/dynamic-point-add-rectangle-sum.hpp | 34 ++++++++----- other/dynamic-rectangle-add-point-get.hpp | 34 ++++++++----- other/mo-rollback.hpp | 29 +++++++---- other/mo.hpp | 23 ++++++--- other/offline-dynamic-connectivity.hpp | 29 +++++++---- other/poyopoyo-pudding.hpp | 34 +++++++++---- other/scanner.hpp | 37 +++++++++----- other/static-point-add-rectangle-sum.hpp | 35 ++++++++----- other/static-range-count-distinct.hpp | 32 ++++++++---- other/static-rectangle-add-point-get.hpp | 38 +++++++++----- other/static-rectangle-add-rectangle-sum.hpp | 36 ++++++++----- other/timer.hpp | 17 ++++--- scripts/self-contained-headers.txt | 40 +++++++++++++++ .../self-contained-header-migration.test.cpp | 51 +++++++++++++++++++ 43 files changed, 709 insertions(+), 323 deletions(-) diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index cc1cbf081..11d0cb18b 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -22,7 +22,7 @@ | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 160 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 200 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -130,6 +130,8 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null | 2026-08-10 | `geometry/integer/point.hpp`、`geometry/convex-layers.hpp`、`structure/others/decremental-upper-hull.hpp` | 標準 include と `std::` 修飾 | | 2026-08-10 | `math/combinatorics/` の18ヘッダー、`math/fft/` の13ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `math/number-theory/` の4ヘッダー、`structure/class/` の3ヘッダー、`other/` の2ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `graph/others/` の16ヘッダー、`graph/mst/` の5ヘッダー、`graph/tree/` の6ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `other/` の14ヘッダー、`math/matrix/binary-basis.hpp` | 標準 include と `std::` 修飾 | ## 次の候補 diff --git a/graph/mst/boruvka.hpp b/graph/mst/boruvka.hpp index 5f8799c1e..2e85f0916 100644 --- a/graph/mst/boruvka.hpp +++ b/graph/mst/boruvka.hpp @@ -1,3 +1,11 @@ +#pragma once + +#include +#include +#include +#include +#include + #include "../../structure/union-find/union-find.hpp" /** @@ -7,12 +15,12 @@ template struct Boruvka { private: - size_t V; + std::size_t V; UnionFind uf; const T INF; public: - explicit Boruvka(size_t V, T INF = numeric_limits::max()) + explicit Boruvka(std::size_t V, T INF = std::numeric_limits::std::max()) : V(V), uf(V), INF(INF) {} inline int find(int k) { return uf.find(k); } @@ -21,7 +29,7 @@ struct Boruvka { T build(const F& update) { T ret = T(); while (uf.size(0) < (int)V) { - vector > v(V, make_pair(INF, -1)); + std::vector > v(V, make_pair(INF, -1)); update(v); bool con = false; for (int i = 0; i < (int)V; i++) { @@ -35,3 +43,4 @@ struct Boruvka { return ret; } }; +#pragma once diff --git a/graph/mst/directed-mst.hpp b/graph/mst/directed-mst.hpp index 55427dad4..09aded734 100644 --- a/graph/mst/directed-mst.hpp +++ b/graph/mst/directed-mst.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "../../structure/heap/skew-heap.hpp" #include "../graph-template.hpp" @@ -20,19 +22,19 @@ MinimumSpanningTree directed_mst(int V, int root, Edges edges) { } int x = 0; - vector par(2 * V, -1), vis(par), link(par); + std::vector par(2 * V, -1), vis(par), link(par); using Heap = SkewHeap; using Node = typename Heap::Node; Heap heap; - vector ins(2 * V, heap.make_root()); + std::vector ins(2 * V, heap.make_root()); for (int i = 0; i < (int)edges.size(); i++) { auto& e = edges[i]; ins[e.to] = heap.push(ins[e.to], e.cost, i); } - vector st; + std::vector st; auto go = [&](int x) { x = edges[ins[x]->idx].from; while (link[x] != -1) { diff --git a/graph/mst/kruskal.hpp b/graph/mst/kruskal.hpp index 0e5d09442..5e7a3aab6 100644 --- a/graph/mst/kruskal.hpp +++ b/graph/mst/kruskal.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../../structure/union-find/union-find.hpp" #include "../graph-template.hpp" @@ -15,8 +18,8 @@ struct MinimumSpanningTree { template MinimumSpanningTree kruskal(Edges& edges, int V) { - sort(begin(edges), end(edges), - [](const Edge& a, const Edge& b) { return a.cost < b.cost; }); + std::sort(std::begin(edges), std::end(edges), + [](const Edge& a, const Edge& b) { return a.cost < b.cost; }); UnionFind tree(V); T total = T(); Edges es; diff --git a/graph/mst/manhattan-mst.hpp b/graph/mst/manhattan-mst.hpp index d00810f57..d0099a135 100644 --- a/graph/mst/manhattan-mst.hpp +++ b/graph/mst/manhattan-mst.hpp @@ -1,33 +1,43 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include +#include + #include "../graph-template.hpp" /** * @brief Manhattan MST */ template -Edges manhattan_mst(vector xs, vector ys) { +Edges manhattan_mst(std::vector xs, std::vector ys) { assert(xs.size() == ys.size()); Edges ret; int n = (int)xs.size(); - vector ord(n); - iota(ord.begin(), ord.end(), 0); + std::vector ord(n); + std::iota(ord.begin(), ord.end(), 0); for (int s = 0; s < 2; s++) { for (int t = 0; t < 2; t++) { auto cmp = [&](int i, int j) -> bool { return xs[i] + ys[i] < xs[j] + ys[j]; }; - sort(ord.begin(), ord.end(), cmp); + std::sort(ord.begin(), ord.end(), cmp); - map idx; + std::map idx; for (int i : ord) { for (auto it = idx.lower_bound(-ys[i]); it != idx.end(); it = idx.erase(it)) { int j = it->second; if (xs[i] - xs[j] < ys[i] - ys[j]) break; - ret.emplace_back(i, j, abs(xs[i] - xs[j]) + abs(ys[i] - ys[j])); + ret.emplace_back(i, j, + std::abs(xs[i] - xs[j]) + std::abs(ys[i] - ys[j])); } idx[-ys[i]] = i; } diff --git a/graph/mst/prim.hpp b/graph/mst/prim.hpp index 4960d1a2d..3889fe844 100644 --- a/graph/mst/prim.hpp +++ b/graph/mst/prim.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" /** @@ -15,10 +20,10 @@ struct MinimumSpanningTree { template MinimumSpanningTree prim(const Graph& g) { T total = T(); - vector used(g.size()); - vector*> dist(g.size()); - using pi = pair; - priority_queue, greater<> > que; + std::vector used(g.size()); + std::vector*> dist(g.size()); + using pi = std::pair; + std::priority_queue, std::greater<> > que; que.emplace(T(), 0); Edges edges; while (!que.empty()) { diff --git a/graph/others/cartesian-tree.hpp b/graph/others/cartesian-tree.hpp index 7539653dc..9cbe602a8 100644 --- a/graph/others/cartesian-tree.hpp +++ b/graph/others/cartesian-tree.hpp @@ -1,12 +1,16 @@ #pragma once + +#include +#include + /** * @brief Cartesian Tree */ template -vector cartesian_tree(const vector& v) { +std::vector cartesian_tree(const std::vector& v) { int n = (int)v.size(); - vector par(n, -1); - stack st; + std::vector par(n, -1); + std::stack st; for (int i = 0; i < n; i++) { int last = -1; while (!st.empty() && v[st.top()] >= v[i]) { diff --git a/graph/others/chromatic-number.hpp b/graph/others/chromatic-number.hpp index 09dfa262f..0e1b5b9e5 100644 --- a/graph/others/chromatic-number.hpp +++ b/graph/others/chromatic-number.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + /** * @brief Chromatic Number(彩色数) * @@ -8,23 +12,23 @@ template int chromatic_number(Matrix& g) { int N = (int)g.size(); - vector es(N); + std::vector es(N); for (int i = 0; i < (int)g.size(); i++) { for (int j = 0; j < (int)g.size(); j++) { if (g[i][j] != 0) es[i] |= 1 << j; } } - vector ind(1 << N); + std::vector ind(1 << N); ind[0] = 1; for (int S = 1; S < (1 << N); S++) { int u = __builtin_ctz(S); ind[S] = ind[S ^ (1 << u)] + ind[(S ^ (1 << u)) & ~es[u]]; } - vector cnt((1 << N) + 1); + std::vector cnt((1 << N) + 1); for (int i = 0; i < (1 << N); i++) { cnt[ind[i]] += __builtin_parity(i) ? -1 : 1; } - vector > hist; + std::vector > hist; for (int i = 1; i <= (1 << N); i++) { if (cnt[i]) hist.emplace_back(i, cnt[i]); } @@ -33,9 +37,9 @@ int chromatic_number(Matrix& g) { for (int k = 0; k < 3; k++) { auto buf = hist; for (int c = 1; c < ret; c++) { - int64_t sum = 0; + std::int64_t sum = 0; for (auto& [i, x] : buf) { - sum += (x = int64_t(x) * i % mods[k]); + sum += (x = std::int64_t(x) * i % mods[k]); } if (sum % mods[k]) ret = c; } diff --git a/graph/others/cycle-detection.hpp b/graph/others/cycle-detection.hpp index c8492b4a9..580c71c33 100644 --- a/graph/others/cycle-detection.hpp +++ b/graph/others/cycle-detection.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "../graph-template.hpp" /** @@ -11,7 +15,7 @@ struct CycleDetection : Graph { using Graph::Graph; using Graph::g; - vector used; + std::vector used; Edges pre, cycle; bool dfs(int idx) { @@ -40,7 +44,7 @@ struct CycleDetection : Graph { pre.resize(g.size()); for (int i = 0; i < (int)g.size(); i++) { if (used[i] == 0 && dfs(i)) { - reverse(begin(cycle), end(cycle)); + std::reverse(std::begin(cycle), std::end(cycle)); return cycle; } } diff --git a/graph/others/dominator-tree.hpp b/graph/others/dominator-tree.hpp index dc063a944..a1f176359 100644 --- a/graph/others/dominator-tree.hpp +++ b/graph/others/dominator-tree.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "../graph-template.hpp" /** @@ -29,8 +33,8 @@ struct DominatorTree : Graph { } } - vector > bucket(N); - vector U(N); + std::vector > bucket(N); + std::vector U(N); for (int i = (int)ord.size() - 1; i >= 0; i--) { int x = ord[i]; for (int v : rg[x]) { @@ -59,13 +63,13 @@ struct DominatorTree : Graph { Graph rg; struct UnionFind { - const vector& semi; - vector par, m; + const std::vector& semi; + std::vector par, m; - explicit UnionFind(const vector& semi) + explicit UnionFind(const std::vector& semi) : semi(semi), par(semi.size()), m(semi.size()) { - iota(begin(par), end(par), 0); - iota(begin(m), end(m), 0); + std::iota(std::begin(par), std::end(par), 0); + std::iota(std::begin(m), std::end(m), 0); } int find(int v) { @@ -83,8 +87,8 @@ struct DominatorTree : Graph { void link(int p, int c) { par[c] = p; } }; - vector ord, par; - vector idom, semi; + std::vector ord, par; + std::vector idom, semi; void dfs(int idx) { semi[idx] = (int)ord.size(); diff --git a/graph/others/enumerate-cliques.hpp b/graph/others/enumerate-cliques.hpp index 38c707709..86ad12a54 100644 --- a/graph/others/enumerate-cliques.hpp +++ b/graph/others/enumerate-cliques.hpp @@ -1,23 +1,29 @@ +#pragma once + +#include +#include +#include + /** * @brief Enumerate Cliques(クリーク全列挙) * @see https://www.slideshare.net/wata_orz/ss-12131479 * */ template -vector > enumerate_cliques(Matrix& g) { +std::vector > enumerate_cliques(Matrix& g) { int N = (int)g.size(), M = 0; - vector deg(N); - vector > edge(N, vector(N)); + std::vector deg(N); + std::vector > edge(N, std::vector(N)); for (int i = 0; i < N; i++) { for (auto p : g[i]) deg[i] += p; M += deg[i]; } - int lim = (int)sqrt(M); + int lim = (int)std::sqrt(M); - vector > cliques; + std::vector > cliques; - auto add_clique = [&](const vector& rem, bool last) { - vector neighbor((int)rem.size() - last); + auto add_clique = [&](const std::vector& rem, bool last) { + std::vector neighbor((int)rem.size() - last); for (int i = 0; i < (int)neighbor.size(); i++) { for (int j = 0; j < (int)neighbor.size(); j++) { if (i != j && !g[rem[i]][rem[j]]) neighbor[i] |= 1 << j; @@ -34,7 +40,7 @@ vector > enumerate_cliques(Matrix& g) { } } if (ok) { - vector clique; + std::vector clique; if (last) clique.emplace_back(rem.back()); for (int j = 0; j < (int)neighbor.size(); j++) { if ((i >> j) & 1) clique.emplace_back(rem[j]); @@ -44,8 +50,8 @@ vector > enumerate_cliques(Matrix& g) { } }; - vector used(N); - queue que; + std::vector used(N); + std::queue que; for (int i = 0; i < N; i++) { if (deg[i] < lim) { used[i] = true; @@ -55,7 +61,7 @@ vector > enumerate_cliques(Matrix& g) { while (!que.empty()) { int idx = que.front(); que.pop(); - vector rem; + std::vector rem; for (int k = 0; k < N; k++) { if (g[idx][k]) rem.emplace_back(k); } @@ -74,10 +80,11 @@ vector > enumerate_cliques(Matrix& g) { } } } - vector rem; + std::vector rem; for (int i = 0; i < N; i++) { if (!used[i]) rem.emplace_back(i); } add_clique(rem, false); return cliques; } +#pragma once diff --git a/graph/others/enumerate-triangles.hpp b/graph/others/enumerate-triangles.hpp index f1defe548..5eb289ca6 100644 --- a/graph/others/enumerate-triangles.hpp +++ b/graph/others/enumerate-triangles.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "../graph-template.hpp" /** @@ -7,14 +11,14 @@ * */ template -vector > enumerate_triangles(const Graph& g) { +std::vector > enumerate_triangles(const Graph& g) { int N = (int)g.size(); - using pi = pair; - vector vp(N); + using pi = std::pair; + std::vector vp(N); for (int i = 0; i < N; i++) { vp[i] = {(int)g[i].size(), i}; } - vector > h(N); + std::vector > h(N); for (int i = 0; i < N; i++) { for (auto& j : g[i]) { if (vp[i] > vp[j]) { @@ -22,8 +26,8 @@ vector > enumerate_triangles(const Graph& g) { } } } - vector > triangle; - vector used(N); + std::vector > triangle; + std::vector used(N); for (int x = 0; x < N; x++) { for (int z : h[x]) used[z] = true; for (int y : h[x]) { diff --git a/graph/others/eulerian-trail.hpp b/graph/others/eulerian-trail.hpp index c7ab5e266..a719b79cd 100644 --- a/graph/others/eulerian-trail.hpp +++ b/graph/others/eulerian-trail.hpp @@ -1,5 +1,12 @@ #pragma once +#include +#include +#include +#include +#include +#include + #include "../../structure/union-find/union-find.hpp" /** @@ -8,10 +15,10 @@ */ template struct EulerianTrail { - vector > > g; - vector > es; + std::vector > > g; + std::vector > es; int M; - vector used_vertex, used_edge, deg; + std::vector used_vertex, used_edge, deg; explicit EulerianTrail(int V) : g(V), M(0), used_vertex(V), deg(V) {} @@ -29,9 +36,9 @@ struct EulerianTrail { M++; } - pair get_edge(int idx) const { return es[idx]; } + std::pair get_edge(int idx) const { return es[idx]; } - vector > enumerate_eulerian_trail() { + std::vector > enumerate_eulerian_trail() { if (directed) { for (auto& p : deg) if (p != 0) return {}; @@ -40,7 +47,7 @@ struct EulerianTrail { if (p & 1) return {}; } used_edge.assign(M, 0); - vector > ret; + std::vector > ret; for (int i = 0; i < (int)g.size(); i++) { if (g[i].empty() || used_vertex[i]) continue; ret.emplace_back(go(i)); @@ -48,19 +55,19 @@ struct EulerianTrail { return ret; } - vector > enumerate_semi_eulerian_trail() { + std::vector > enumerate_semi_eulerian_trail() { UnionFind uf(g.size()); for (auto& p : es) uf.unite(p.first, p.second); - vector > group(g.size()); + std::vector > group(g.size()); for (int i = 0; i < (int)g.size(); i++) group[uf.find(i)].emplace_back(i); - vector > ret; + std::vector > ret; used_edge.assign(M, 0); for (auto& vs : group) { if (vs.empty()) continue; int latte = -1, malta = -1; if (directed) { for (auto& p : vs) { - if (abs(deg[p]) > 1) { + if (std::abs(deg[p]) > 1) { return {}; } else if (deg[p] == 1) { if (latte >= 0) return {}; @@ -85,9 +92,9 @@ struct EulerianTrail { return ret; } - vector go(int s) { - stack > st; - vector ord; + std::vector go(int s) { + std::stack > st; + std::vector ord; st.emplace(s, -1); while (!st.empty()) { int idx = st.top().first; @@ -104,7 +111,7 @@ struct EulerianTrail { } } ord.pop_back(); - reverse(ord.begin(), ord.end()); + std::reverse(ord.begin(), ord.end()); return ord; } }; diff --git a/graph/others/extreme-vertex-set.hpp b/graph/others/extreme-vertex-set.hpp index 98afdfe5e..4c2d741b5 100644 --- a/graph/others/extreme-vertex-set.hpp +++ b/graph/others/extreme-vertex-set.hpp @@ -1,3 +1,13 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + #include "../graph-template.hpp" template @@ -8,20 +18,20 @@ Graph extreme_vertex_set(int n, const Edges& es) { assert(e.from != e.to); assert(0 <= e.cost); } - using pi = pair; + using pi = std::pair; Graph res(2 * n - 1); - vector uf(n); - vector cur(2 * n - 1); - iota(uf.begin(), uf.end(), 0); - vector leaf(2 * n - 1); + std::vector uf(n); + std::vector cur(2 * n - 1); + std::iota(uf.begin(), uf.end(), 0); + std::vector leaf(2 * n - 1); for (int i = 0; i < n; i++) { leaf[i] = true; } - using qi = pair; - priority_queue, greater<> > que; + using qi = std::pair; + std::priority_queue, std::greater<> > que; for (int phase = 0; phase < n - 1; phase++) { Graph g(2 * n - 1); - vector cost(2 * n - 1); + std::vector cost(2 * n - 1); for (auto e : es) { e.from = uf[e.from]; e.to = uf[e.to]; @@ -68,3 +78,4 @@ Graph extreme_vertex_set(int n, const Edges& es) { } return res; } +#pragma once diff --git a/graph/others/low-link.hpp b/graph/others/low-link.hpp index 2c9c0526f..55ec8d6e9 100644 --- a/graph/others/low-link.hpp +++ b/graph/others/low-link.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "../graph-template.hpp" /** @@ -11,8 +15,8 @@ template struct LowLink : Graph { public: using Graph::Graph; - vector ord, low, articulation; - vector > bridge; + std::vector ord, low, articulation; + std::vector > bridge; using Graph::g; virtual void build() { @@ -28,7 +32,7 @@ struct LowLink : Graph { explicit LowLink(const Graph& g) : Graph(g) {} private: - vector used; + std::vector used; int dfs(int idx, int k, int par) { used[idx] = true; @@ -37,17 +41,17 @@ struct LowLink : Graph { bool is_articulation = false, beet = false; int cnt = 0; for (auto& to : g[idx]) { - if (to == par && !exchange(beet, true)) { + if (to == par && !std::exchange(beet, true)) { continue; } if (!used[to]) { ++cnt; k = dfs(to, k, idx); - low[idx] = min(low[idx], low[to]); + low[idx] = std::min(low[idx], low[to]); is_articulation |= par >= 0 && low[to] >= ord[idx]; if (ord[idx] < low[to]) bridge.emplace_back(to); } else { - low[idx] = min(low[idx], ord[to]); + low[idx] = std::min(low[idx], ord[to]); } } is_articulation |= par == -1 && cnt > 1; diff --git a/graph/others/maximum-clique.hpp b/graph/others/maximum-clique.hpp index c9ac38e46..c60cd0a3d 100644 --- a/graph/others/maximum-clique.hpp +++ b/graph/others/maximum-clique.hpp @@ -1,12 +1,19 @@ #pragma once +#include +#include +#include +#include +#include +#include + /** * @brief Maximum Clique(最大クリーク) */ template struct MaximumClique { - using B = bitset; - vector g, col_buf; + using B = std::bitset; + std::vector g, col_buf; struct P { int idx, col, deg; @@ -23,26 +30,26 @@ struct MaximumClique { g[b].set(a); } - vector now, clique; + std::vector now, clique; - void dfs(vector

& rem) { + void dfs(std::vector

& rem) { if (clique.size() < now.size()) clique = now; - sort(begin(rem), end(rem), - [](const P& a, const P& b) { return a.deg > b.deg; }); + std::sort(std::begin(rem), std::end(rem), + [](const P& a, const P& b) { return a.deg > b.deg; }); int max_c = 1; for (auto& p : rem) { p.col = 0; while ((g[p.idx] & col_buf[p.col]).any()) ++p.col; - max_c = max(max_c, p.idx + 1); + max_c = std::max(max_c, p.idx + 1); col_buf[p.col].set(p.idx); } for (int i = 0; i < max_c; i++) col_buf[i].reset(); - sort(begin(rem), end(rem), - [&](const P& a, const P& b) { return a.col < b.col; }); + std::sort(std::begin(rem), std::end(rem), + [&](const P& a, const P& b) { return a.col < b.col; }); for (; !rem.empty(); rem.pop_back()) { auto& p = rem.back(); if (now.size() + p.col + 1 <= clique.size()) break; - vector

nrem; + std::vector

nrem; B bs; for (auto& q : rem) { if (g[p.idx][q.idx]) { @@ -59,9 +66,9 @@ struct MaximumClique { } } - vector solve() { - vector

remark; - for (size_t i = 0; i < g.size(); i++) { + std::vector solve() { + std::vector

remark; + for (std::size_t i = 0; i < g.size(); i++) { remark.emplace_back(i, -1, (int)g[i].size()); } dfs(remark); diff --git a/graph/others/maximum-independent-set.hpp b/graph/others/maximum-independent-set.hpp index 485261673..7f1db704a 100644 --- a/graph/others/maximum-independent-set.hpp +++ b/graph/others/maximum-independent-set.hpp @@ -1,32 +1,44 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + /** + * @brief Maximum Independent Set(最大独立集合) */ template -vector maximum_independent_set(const Matrix& g, int trial = 1000000) { +std::vector maximum_independent_set(const Matrix& g, int trial = 1000000) { int N = (int)g.size(); - vector bit(N); + std::vector bit(N); assert(N <= 64); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (i != j) { assert(g[i][j] == g[j][i]); - if (g[i][j]) bit[i] |= uint64_t(1) << j; + if (g[i][j]) bit[i] |= std::uint64_t(1) << j; } } } - vector ord(N); - iota(begin(ord), end(ord), 0); - mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); + std::vector ord(N); + std::iota(std::begin(ord), std::end(ord), 0); + std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count()); int ret = 0; - uint64_t ver = 0; + std::uint64_t ver = 0; for (int i = 0; i < trial; i++) { - shuffle(begin(ord), end(ord), mt); - uint64_t used = 0; + std::shuffle(std::begin(ord), std::end(ord), mt); + std::uint64_t used = 0; int add = 0; for (int j : ord) { if (used & bit[j]) continue; - used |= uint64_t(1) << j; + used |= std::uint64_t(1) << j; ++add; } if (ret < add) { @@ -34,9 +46,10 @@ vector maximum_independent_set(const Matrix& g, int trial = 1000000) { ver = used; } } - vector ans; + std::vector ans; for (int i = 0; i < N; i++) { if ((ver >> i) & 1) ans.emplace_back(i); } return ans; } +#pragma once diff --git a/graph/others/minimum-steiner-tree.hpp b/graph/others/minimum-steiner-tree.hpp index c1c81d298..82763e060 100644 --- a/graph/others/minimum-steiner-tree.hpp +++ b/graph/others/minimum-steiner-tree.hpp @@ -1,29 +1,40 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + #include "../graph-template.hpp" template struct MinimumSteinerTree { - using pi = pair; + using pi = std::pair; - const T infty = numeric_limits::max(); + const T infty = std::numeric_limits::std::max(); - vector > dp; + std::vector > dp; T cost; MinimumSteinerTree() = default; - explicit MinimumSteinerTree(const Graph& g, const vector& terminal) + explicit MinimumSteinerTree(const Graph& g, + const std::vector& terminal) : g(g), terminal(terminal), - dp(1 << terminal.size(), vector(g.size(), infty)), - pre(1 << terminal.size(), vector(g.size(), pi(-1, -1))) { + dp(1 << terminal.size(), std::vector(g.size(), infty)), + pre(1 << terminal.size(), std::vector(g.size(), pi(-1, -1))) { assert(not terminal.empty()); const int n = (int)g.size(), t = (int)terminal.size(); for (int i = 0; i < t; i++) { assert(0 <= terminal[i] and terminal[i] < n); dp[1 << i][terminal[i]] = 0; } - using qt = pair; - priority_queue, greater<> > que; + using qt = std::pair; + std::priority_queue, std::greater<> > que; for (int i = 1; i < (1 << t); i++) { for (int j = 0; j < n; j++) { for (int k = i; k > 0; k = (k - 1) & i) { @@ -62,7 +73,7 @@ struct MinimumSteinerTree { const int t = (int)terminal.size(); assert(dp[(1 << t) - 1][terminal[0]] != infty); Edges tree; - vector > st; + std::vector > st; st.emplace_back((1 << t) - 1, terminal[0]); while (not st.empty()) { auto [x, y] = st.back(); @@ -82,6 +93,7 @@ struct MinimumSteinerTree { private: const Graph& g; - const vector& terminal; - vector > pre; + const std::vector& terminal; + std::vector > pre; }; +#pragma once diff --git a/graph/others/namori-graph.hpp b/graph/others/namori-graph.hpp index 07f492ec2..3415af32d 100644 --- a/graph/others/namori-graph.hpp +++ b/graph/others/namori-graph.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "../graph-template.hpp" /** @@ -12,7 +16,7 @@ struct NamoriGraph : Graph { using Graph::Graph; using Graph::g; - vector > forest; + std::vector > forest; Edges loop_edges; struct Info { @@ -25,8 +29,8 @@ struct NamoriGraph : Graph { void build() { int n = (int)g.size(); - vector deg(n), used(n); - queue que; + std::vector deg(n), used(n); + std::queue que; for (int i = 0; i < n; i++) { deg[i] = (int)g[i].size(); if (deg[i] == 1) { @@ -50,10 +54,10 @@ struct NamoriGraph : Graph { } int mx = 0; for (auto& edges : g) { - for (auto& e : edges) mx = max(mx, e.idx); + for (auto& e : edges) mx = std::max(mx, e.idx); } - vector edge_used(mx + 1); - vector loop; + std::vector edge_used(mx + 1); + std::vector loop; for (int v = 0; v < n; v++) { if (!used[v]) { for (bool update = true; update;) { @@ -103,8 +107,8 @@ struct NamoriGraph : Graph { } private: - vector > iv; - vector mark_id, id; + std::vector > iv; + std::vector mark_id, id; void mark_dfs(int idx, int par, int k, int& l) { mark_id[idx] = k; diff --git a/graph/others/offline-dag-reachability.hpp b/graph/others/offline-dag-reachability.hpp index bdabd1d52..c8eceacfe 100644 --- a/graph/others/offline-dag-reachability.hpp +++ b/graph/others/offline-dag-reachability.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" #include "topological-sort.hpp" @@ -9,17 +14,17 @@ */ template -vector offline_dag_reachability(const Graph& g, - vector >& qs) { +std::vector offline_dag_reachability( + const Graph& g, std::vector >& qs) { const int N = (int)g.size(); const int Q = (int)qs.size(); auto ord = topological_sort(g); - vector ans(Q); + std::vector ans(Q); for (int l = 0; l < Q; l += 64) { - int r = min(Q, l + 64); - vector dp(N); + int r = std::min(Q, l + 64); + std::vector dp(N); for (int k = l; k < r; k++) { - dp[qs[k].first] |= int64_t(1) << (k - l); + dp[qs[k].first] |= std::int64_t(1) << (k - l); } for (auto& idx : ord) { for (auto& to : g[idx]) dp[to] |= dp[idx]; diff --git a/graph/others/topological-sort.hpp b/graph/others/topological-sort.hpp index 9d6940cd5..ed50fce07 100644 --- a/graph/others/topological-sort.hpp +++ b/graph/others/topological-sort.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../graph-template.hpp" /** @@ -7,17 +10,17 @@ * */ template -vector topological_sort(const Graph& g) { +std::vector topological_sort(const Graph& g) { const int N = (int)g.size(); - vector deg(N); + std::vector deg(N); for (int i = 0; i < N; i++) { for (auto& to : g[i]) ++deg[to]; } - stack st; + std::stack st; for (int i = 0; i < N; i++) { if (deg[i] == 0) st.emplace(i); } - vector ord; + std::vector ord; while (!st.empty()) { auto p = st.top(); st.pop(); diff --git a/graph/others/tree-decomposition-width-2.hpp b/graph/others/tree-decomposition-width-2.hpp index 49c52de04..a9cf9fb51 100644 --- a/graph/others/tree-decomposition-width-2.hpp +++ b/graph/others/tree-decomposition-width-2.hpp @@ -1,18 +1,26 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include + /** * @brief Tree Decomposition Width 2(木幅2の木分解) * @see https://ei1333.hateblo.jp/entry/2020/02/12/150319 * */ struct DecompNode { - vector bag, child; + std::vector bag, child; DecompNode() = default; }; struct TreeDecompositionWidth2 { - vector > g; + std::vector > g; explicit TreeDecompositionWidth2(int V) : g(V) {} @@ -21,24 +29,24 @@ struct TreeDecompositionWidth2 { g[b].emplace_back(a); } - vector build() { + std::vector build() { const int N = (int)g.size(); - vector used(N, -1), deg(N); - queue que; + std::vector used(N, -1), deg(N); + std::queue que; for (int i = 0; i < N; i++) { deg[i] = (int)g[i].size(); if (deg[i] <= 2) que.emplace(i); } - vector > exists(N); + std::vector > exists(N); for (int i = 0; i < N; i++) { for (auto& j : g[i]) { if (i < j) exists[i].emplace(j); } } - vector ret; + std::vector ret; ret.emplace_back(); while (!que.empty()) { int idx = que.front(); @@ -62,7 +70,7 @@ struct TreeDecompositionWidth2 { } else if (v == -1) { --deg[u]; } else { - if (u > v) swap(u, v); + if (u > v) std::swap(u, v); if (!exists[u].count(v)) { g[u].emplace_back(v); g[v].emplace_back(u); @@ -90,12 +98,12 @@ struct TreeDecompositionWidth2 { } }; -void to_nice(vector& g, int root = 0) { +void to_nice(std::vector& g, int root = 0) { for (auto& p : g) { - sort(p.bag.begin(), p.bag.end()); + std::sort(p.bag.begin(), p.bag.end()); } - stack st; + std::stack st; st.emplace(root); while (!st.empty()) { @@ -131,7 +139,7 @@ void to_nice(vector& g, int root = 0) { if (g[idx].child.size() == 1) { int& ch = g[idx].child[0]; - vector latte, malta; + std::vector latte, malta; set_difference(g[idx].bag.begin(), g[idx].bag.end(), g[ch].bag.begin(), g[ch].bag.end(), back_inserter(latte)); set_difference(g[ch].bag.begin(), g[ch].bag.end(), g[idx].bag.begin(), diff --git a/graph/tree/centroid.hpp b/graph/tree/centroid.hpp index 2dd47da23..eca025bc8 100644 --- a/graph/tree/centroid.hpp +++ b/graph/tree/centroid.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" /** @@ -7,12 +12,12 @@ * */ template -vector centroid(const Graph& g) { +std::vector centroid(const Graph& g) { const int N = (int)g.size(); - stack > st; + std::stack > st; st.emplace(0, -1); - vector sz(N), par(N); + std::vector sz(N), par(N); while (!st.empty()) { auto p = st.top(); if (sz[p.first] == 0) { @@ -27,12 +32,12 @@ vector centroid(const Graph& g) { } } - vector ret; + std::vector ret; int size = N; for (int i = 0; i < N; i++) { int val = N - sz[i]; for (auto& to : g[i]) - if (to != par[i]) val = max(val, sz[to]); + if (to != par[i]) val = std::max(val, sz[to]); if (val < size) size = val, ret.clear(); if (val == size) ret.emplace_back(i); } diff --git a/graph/tree/convert-rooted-tree.hpp b/graph/tree/convert-rooted-tree.hpp index e33de5799..b37b20238 100644 --- a/graph/tree/convert-rooted-tree.hpp +++ b/graph/tree/convert-rooted-tree.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../graph-template.hpp" /** @@ -9,9 +12,9 @@ template Graph convert_rooted_tree(const Graph& g, int r = 0) { int N = (int)g.size(); Graph rg(N); - vector v(N); + std::vector v(N); v[r] = 1; - queue que; + std::queue que; que.emplace(r); while (!que.empty()) { auto p = que.front(); diff --git a/graph/tree/heavy-light-decomposition.hpp b/graph/tree/heavy-light-decomposition.hpp index 50aa386bc..43e936326 100644 --- a/graph/tree/heavy-light-decomposition.hpp +++ b/graph/tree/heavy-light-decomposition.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" /** @@ -11,7 +16,7 @@ struct HeavyLightDecomposition : Graph { public: using Graph::Graph; using Graph::g; - vector sz, in, out, head, rev, par, dep; + std::vector sz, in, out, head, rev, par, dep; void build(int root = 0) { sz.assign(g.size(), 0); @@ -39,7 +44,7 @@ struct HeavyLightDecomposition : Graph { int lca(int u, int v) const { for (;; v = par[head[v]]) { - if (in[u] > in[v]) swap(u, v); + if (in[u] > in[v]) std::swap(u, v); if (head[u] == head[v]) return u; } } @@ -51,7 +56,7 @@ struct HeavyLightDecomposition : Graph { bool edge = false) { E l = ti, r = ti; for (;; v = par[head[v]]) { - if (in[u] > in[v]) swap(u, v), swap(l, r); + if (in[u] > in[v]) std::swap(u, v), std::swap(l, r); if (head[u] == head[v]) break; l = f(q(in[head[v]], in[v] + 1), l); } @@ -67,7 +72,7 @@ struct HeavyLightDecomposition : Graph { template void add(int u, int v, const Q& q, bool edge = false) { for (;; v = par[head[v]]) { - if (in[u] > in[v]) swap(u, v); + if (in[u] > in[v]) std::swap(u, v); if (head[u] == head[v]) break; q(in[head[v]], in[v] + 1); } @@ -75,7 +80,7 @@ struct HeavyLightDecomposition : Graph { } /* {parent, child} */ - vector > compress(vector& remark) { + std::vector > compress(std::vector& remark) { auto cmp = [&](int a, int b) { return in[a] < in[b]; }; sort(begin(remark), end(remark), cmp); remark.erase(unique(begin(remark), end(remark)), end(remark)); @@ -84,8 +89,8 @@ struct HeavyLightDecomposition : Graph { remark.emplace_back(lca(remark[k - 1], remark[k])); sort(begin(remark), end(remark), cmp); remark.erase(unique(begin(remark), end(remark)), end(remark)); - vector > es; - stack st; + std::vector > es; + std::stack st; for (auto& k : remark) { while (!st.empty() && out[st.top()] <= in[k]) st.pop(); if (!st.empty()) es.emplace_back(st.top(), k); @@ -101,12 +106,12 @@ struct HeavyLightDecomposition : Graph { dep[idx] = d; par[idx] = p; sz[idx] = 1; - if (g[idx].size() && g[idx][0] == p) swap(g[idx][0], g[idx].back()); + if (g[idx].size() && g[idx][0] == p) std::swap(g[idx][0], g[idx].back()); for (auto& to : g[idx]) { if (to == p) continue; dfs_sz(to, idx, d + 1); sz[idx] += sz[to]; - if (sz[g[idx][0]] < sz[to]) swap(g[idx][0], to); + if (sz[g[idx][0]] < sz[to]) std::swap(g[idx][0], to); } } diff --git a/graph/tree/rerooting.hpp b/graph/tree/rerooting.hpp index ecda04031..9b0d3762b 100644 --- a/graph/tree/rerooting.hpp +++ b/graph/tree/rerooting.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + template struct ReRooting { struct Edge { @@ -6,14 +11,14 @@ struct ReRooting { sum_t dp, ndp; }; - using F = function; - using G = function; + using F = std::function; + using G = std::function; - vector > g; + std::vector > g; const F f; const G gg; const sum_t ident; - vector subdp, dp; + std::vector subdp, dp; ReRooting(int V, const F f, const G g, const sum_t& ident) : g(V), f(f), gg(g), ident(ident), subdp(V, ident), dp(V, ident) {} @@ -54,7 +59,7 @@ struct ReRooting { } } - vector build() { + std::vector build() { dfs_sub(0, -1); dfs_all(0, -1, ident); return dp; diff --git a/graph/tree/tree-diameter.hpp b/graph/tree/tree-diameter.hpp index e8f95a3a7..813b7889f 100644 --- a/graph/tree/tree-diameter.hpp +++ b/graph/tree/tree-diameter.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../graph-template.hpp" /** @@ -11,7 +14,7 @@ struct TreeDiameter : Graph { public: using Graph::Graph; using Graph::g; - vector > path; + std::vector > path; T build() { to.assign(g.size(), -1); @@ -33,10 +36,10 @@ struct TreeDiameter : Graph { explicit TreeDiameter(const Graph& g) : Graph(g) {} private: - vector to; + std::vector to; - pair dfs(int idx, int par) { - pair ret(0, idx); + std::pair dfs(int idx, int par) { + std::pair ret(0, idx); for (auto& e : g[idx]) { if (e.to == par) continue; auto cost = dfs(e.to, idx); diff --git a/math/matrix/binary-basis.hpp b/math/matrix/binary-basis.hpp index 12f3bcbac..52802114b 100644 --- a/math/matrix/binary-basis.hpp +++ b/math/matrix/binary-basis.hpp @@ -1,13 +1,22 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + template struct BinaryBasis { - vector basis; + std::vector basis; bool update; BinaryBasis() : update(false) {} bool add(T bit) { for (auto& p : basis) { - bit = min(bit, bit ^ p); + bit = std::min(bit, bit ^ p); } if (bit) { basis.emplace_back(bit); @@ -19,7 +28,7 @@ struct BinaryBasis { bool check(T bit) const { for (auto& p : basis) { - bit = min(bit, bit ^ p); + bit = std::min(bit, bit ^ p); } return bit == 0; } @@ -27,13 +36,14 @@ struct BinaryBasis { void normalize() { sweep(); for (int i = (int)basis.size() - 1; i >= 0; i--) { - for (int j = i - 1; j >= 0; j--) chmin(basis[i], basis[i] ^ basis[j]); + for (int j = i - 1; j >= 0; j--) + basis[i] = std::min(basis[i], basis[i] ^ basis[j]); } } void sweep() { - if (exchange(update, false)) { - sort(begin(basis), end(basis)); + if (std::exchange(update, false)) { + std::sort(std::begin(basis), std::end(basis)); } } @@ -42,7 +52,7 @@ struct BinaryBasis { return basis == a.basis; } - T get_kth(int64_t k) { /* 0-indexed */ + T get_kth(std::int64_t k) { /* 0-indexed */ if ((1LL << basis.size()) <= k) { return -1; } @@ -50,14 +60,15 @@ struct BinaryBasis { sweep(); for (int i = (int)basis.size() - 1; i >= 0; i--) { if (k < (1LL << i)) { - ret = min(ret, ret ^ basis[i]); + ret = std::min(ret, ret ^ basis[i]); } else { k -= 1LL << i; - ret = max(ret, ret ^ basis[i]); + ret = std::max(ret, ret ^ basis[i]); } } return ret; } - size_t size() const { return basis.size(); } + std::size_t size() const { return basis.size(); } }; +#pragma once diff --git a/other/connected-grid-states.hpp b/other/connected-grid-states.hpp index 0f7849f44..5bc53ce77 100644 --- a/other/connected-grid-states.hpp +++ b/other/connected-grid-states.hpp @@ -1,7 +1,17 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + struct ConnectedGridStates { private: - vector > > states; - vector > nxt_wall, nxt_ground; + std::vector > > states; + std::vector > nxt_wall, nxt_ground; int width; public: @@ -9,8 +19,8 @@ struct ConnectedGridStates { : width(width), states(width), nxt_wall(width), nxt_ground(width) { assert(width > 0); - auto modify = [&](vector B) { - vector id(width, -1); + auto modify = [&](std::vector B) { + std::vector id(width, -1); int now = 0; for (int i = 0; i < width; i++) { if (B[i] != -1) { @@ -23,11 +33,11 @@ struct ConnectedGridStates { return B; }; - vector, int> > ids(width); - queue > que; // {col, state_id} + std::vector, int> > ids(width); + std::queue > que; // {col, state_id} { - vector state(width, -1); + std::vector state(width, -1); states[0].emplace_back(state); ids[0].emplace(state, 0); nxt_wall[0].emplace_back(-1); @@ -35,7 +45,7 @@ struct ConnectedGridStates { que.emplace(0, 0); } - auto push = [&](int nxt, const vector& state) -> int { + auto push = [&](int nxt, const std::vector& state) -> int { auto it = ids[nxt].emplace(state, states[nxt].size()); if (it.second) { states[nxt].emplace_back(state); @@ -116,7 +126,8 @@ struct ConnectedGridStates { inline int set_ground(int k, int state) const { return nxt_ground[k][state]; } - inline const vector >& operator[](int k) const { + inline const std::vector >& operator[](int k) const { return states[k >= width ? k - width : k]; } }; +#pragma once diff --git a/other/dynamic-point-add-rectangle-sum.hpp b/other/dynamic-point-add-rectangle-sum.hpp index d343c25bd..f35137bb0 100644 --- a/other/dynamic-point-add-rectangle-sum.hpp +++ b/other/dynamic-point-add-rectangle-sum.hpp @@ -1,10 +1,19 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + #include "static-point-add-rectangle-sum.hpp" template struct DynamicPointAddRectangleSum { using StaticRectangleSumSolver = StaticPointAddRectangleSum; - static_assert(is_integral::value, + static_assert(std::is_integral::value, "template parameter T must be integral type"); struct Point { @@ -16,7 +25,7 @@ struct DynamicPointAddRectangleSum { T l, d, r, u; }; - vector > queries; + std::vector > queries; DynamicPointAddRectangleSum() = default; @@ -29,17 +38,17 @@ struct DynamicPointAddRectangleSum { queries.emplace_back(Query{l, d, r, u}); } - vector calculate_queries() { + std::vector calculate_queries() { int q = (int)queries.size(); - vector rev(q); + std::vector rev(q); int sz = 0; for (int i = 0; i < q; i++) { - if (holds_alternative(queries[i])) { + if (std::holds_alternative(queries[i])) { rev[i] = sz++; } } - vector ans(sz); - queue > range; + std::vector ans(sz); + std::queue > range; range.emplace(0, q); while (not range.empty()) { auto [l, r] = range.front(); @@ -47,20 +56,20 @@ struct DynamicPointAddRectangleSum { int m = (l + r) >> 1; StaticRectangleSumSolver solver; for (int k = l; k < m; k++) { - if (holds_alternative(queries[k])) { - auto& point = get(queries[k]); + if (std::holds_alternative(queries[k])) { + auto& point = std::get(queries[k]); solver.add_point(point.x, point.y, point.w); } } for (int k = m; k < r; k++) { - if (holds_alternative(queries[k])) { - auto& query = get(queries[k]); + if (std::holds_alternative(queries[k])) { + auto& query = std::get(queries[k]); solver.add_query(query.l, query.d, query.r, query.u); } } auto sub = solver.calculate_queries(); for (int k = m, t = 0; k < r; k++) { - if (holds_alternative(queries[k])) { + if (std::holds_alternative(queries[k])) { ans[rev[k]] += sub[t++]; } } @@ -70,3 +79,4 @@ struct DynamicPointAddRectangleSum { return ans; } }; +#pragma once diff --git a/other/dynamic-rectangle-add-point-get.hpp b/other/dynamic-rectangle-add-point-get.hpp index f3fbac880..7cb402966 100644 --- a/other/dynamic-rectangle-add-point-get.hpp +++ b/other/dynamic-rectangle-add-point-get.hpp @@ -1,3 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + #include "static-rectangle-add-point-get.hpp" template @@ -5,7 +14,7 @@ struct DynamicRectangleAddPointGet { private: using StaticPointGetSolver = StaticRectangleAddPointGet; - static_assert(is_integral::value, + static_assert(std::is_integral::value, "template parameter T must be integral type"); struct Rectangle { @@ -17,7 +26,7 @@ struct DynamicRectangleAddPointGet { T x, y; }; - vector > queries; + std::vector > queries; public: DynamicRectangleAddPointGet() = default; @@ -30,17 +39,17 @@ struct DynamicRectangleAddPointGet { void add_query(T x, T y) { queries.emplace_back(Query{x, y}); } - vector calculate_queries() const { + std::vector calculate_queries() const { int q = (int)queries.size(); - vector rev(q); + std::vector rev(q); int sz = 0; for (int i = 0; i < q; i++) { - if (holds_alternative(queries[i])) { + if (std::holds_alternative(queries[i])) { rev[i] = sz++; } } - vector ans(sz); - queue > range; + std::vector ans(sz); + std::queue > range; range.emplace(0, q); while (not range.empty()) { auto [l, r] = range.front(); @@ -48,20 +57,20 @@ struct DynamicRectangleAddPointGet { int m = (l + r) >> 1; StaticPointGetSolver solver; for (int k = l; k < m; k++) { - if (holds_alternative(queries[k])) { - auto& rect = get(queries[k]); + if (std::holds_alternative(queries[k])) { + auto& rect = std::get(queries[k]); solver.add_rectangle(rect.l, rect.d, rect.r, rect.u, rect.w); } } for (int k = m; k < r; k++) { - if (holds_alternative(queries[k])) { - auto& query = get(queries[k]); + if (std::holds_alternative(queries[k])) { + auto& query = std::get(queries[k]); solver.add_query(query.x, query.y); } } auto sub = solver.calculate_queries(); for (int k = m, t = 0; k < r; k++) { - if (holds_alternative(queries[k])) { + if (std::holds_alternative(queries[k])) { ans[rev[k]] += sub[t++]; } } @@ -71,3 +80,4 @@ struct DynamicRectangleAddPointGet { return ans; } }; +#pragma once diff --git a/other/mo-rollback.hpp b/other/mo-rollback.hpp index 59e68c658..b56e3da5a 100644 --- a/other/mo-rollback.hpp +++ b/other/mo-rollback.hpp @@ -1,15 +1,25 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + struct MoRollBack { - using ADD = function; - using REM = function; - using RESET = function; - using SNAPSHOT = function; - using ROLLBACK = function; + using ADD = std::function; + using REM = std::function; + using RESET = std::function; + using SNAPSHOT = std::function; + using ROLLBACK = std::function; int width; - vector left, right, order; + std::vector left, right, order; - MoRollBack(int N, int Q) : width((int)sqrt(N)), order(Q) { - iota(begin(order), end(order), 0); + MoRollBack(int N, int Q) : width((int)std::sqrt(N)), order(Q) { + std::iota(std::begin(order), std::end(order), 0); } void add(int l, int r) { /* [l, r) */ @@ -20,7 +30,7 @@ struct MoRollBack { int run(const ADD& add, const REM& rem, const RESET& reset, const SNAPSHOT& snapshot, const ROLLBACK& rollback) { assert(left.size() == order.size()); - sort(begin(order), end(order), [&](int a, int b) { + std::sort(std::begin(order), std::end(order), [&](int a, int b) { int ablock = left[a] / width, bblock = left[b] / width; if (ablock != bblock) return ablock < bblock; return right[a] < right[b]; @@ -50,3 +60,4 @@ struct MoRollBack { } } }; +#pragma once diff --git a/other/mo.hpp b/other/mo.hpp index 11e2193ac..038498b4a 100644 --- a/other/mo.hpp +++ b/other/mo.hpp @@ -1,13 +1,23 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + struct Mo { private: int n, w; - vector ord; - vector > lr; + std::vector ord; + std::vector > lr; public: Mo(int n, int q) : n(n), ord(q) { - w = max(1, n / max(1.0, sqrt(q * 2.0 / 3.0))); - iota(ord.begin(), ord.end(), 0); + w = std::max(1, n / std::max(1.0, std::sqrt(q * 2.0 / 3.0))); + std::iota(ord.begin(), ord.end(), 0); lr.reserve(q); } @@ -21,7 +31,7 @@ struct Mo { const EL& erase_left, const ER& erase_right, const Q& query) { assert(lr.size() == ord.size()); - vector bs(n); + std::vector bs(n); for (int i = 0, cnt = 0, b = 0; i < n; i++) { bs[i] = b; if (++cnt == w) { @@ -29,7 +39,7 @@ struct Mo { cnt = 0; } } - sort(ord.begin(), ord.end(), [&](int a, int b) { + std::sort(ord.begin(), ord.end(), [&](int a, int b) { int a_block = bs[lr[a].first]; int b_block = bs[lr[b].first]; if (a_block != b_block) return a_block < b_block; @@ -53,3 +63,4 @@ struct Mo { calclate_queries(add, add, erase, erase, query); } }; +#pragma once diff --git a/other/offline-dynamic-connectivity.hpp b/other/offline-dynamic-connectivity.hpp index df97849b2..a54b359c6 100644 --- a/other/offline-dynamic-connectivity.hpp +++ b/other/offline-dynamic-connectivity.hpp @@ -1,13 +1,23 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "../structure/union-find/union-find-undo.hpp" + struct OfflineDynamicConnectivity { - using edge = pair; + using edge = std::pair; UnionFindUndo uf; int V, Q, segsz; - vector > seg; + std::vector > seg; int comp; - vector, edge> > pend; - map cnt, appear; + std::vector, edge> > pend; + std::map cnt, appear; OfflineDynamicConnectivity(int V, int Q) : uf(V), V(V), Q(Q), comp(V) { segsz = 1; @@ -16,13 +26,13 @@ struct OfflineDynamicConnectivity { } void insert(int idx, int s, int t) { - auto e = minmax(s, t); + auto e = std::minmax(s, t); if (cnt[e]++ == 0) appear[e] = idx; } void erase(int idx, int s, int t) { - auto e = minmax(s, t); - if (--cnt[e] == 0) pend.emplace_back(make_pair(appear[e], idx), e); + auto e = std::minmax(s, t); + if (--cnt[e] == 0) pend.emplace_back(std::make_pair(appear[e], idx), e); } void add(int a, int b, const edge& e, int k, int l, int r) { @@ -40,14 +50,14 @@ struct OfflineDynamicConnectivity { void build() { for (auto& p : cnt) { if (p.second > 0) - pend.emplace_back(make_pair(appear[p.first], Q), p.first); + pend.emplace_back(std::make_pair(appear[p.first], Q), p.first); } for (auto& s : pend) { add(s.first.first, s.first.second, s.second); } } - void run(const function& f, int k = 0) { + void run(const std::function& f, int k = 0) { int add = 0; for (auto& e : seg[k]) { add += uf.unite(e.first, e.second); @@ -66,3 +76,4 @@ struct OfflineDynamicConnectivity { comp += add; } }; +#pragma once diff --git a/other/poyopoyo-pudding.hpp b/other/poyopoyo-pudding.hpp index 3c9386381..9cac0ff32 100644 --- a/other/poyopoyo-pudding.hpp +++ b/other/poyopoyo-pudding.hpp @@ -1,3 +1,14 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + /** * 🍮 PoyoPoyoPudding 🍮 * @@ -9,18 +20,18 @@ */ struct PoyoPoyoPudding { struct Layer { - uint8_t sweetness; // 0-100 - uint8_t springiness; // 0-100 + std::uint8_t sweetness; // 0-100 + std::uint8_t springiness; // 0-100 }; - static constexpr size_t kMaxLayers = 10; + static constexpr std::size_t kMaxLayers = 10; // ---- 状態 ---- // std::array layers{}; std::size_t top = 0; // 現在の層数 // ---- 挙動 ---- // - bool addLayer(uint8_t sweet, uint8_t spring) { + bool addLayer(std::uint8_t sweet, std::uint8_t spring) { if (top == kMaxLayers) return false; layers[top++] = {sweet, spring}; return true; @@ -33,25 +44,26 @@ struct PoyoPoyoPudding { } void shake() { - mt19937 rng{static_cast( + std::mt19937 rng{static_cast( std::chrono::steady_clock::now().time_since_epoch().count())}; std::uniform_int_distribution dist(-5, +5); for (std::size_t i = 0; i < top; ++i) { int v = static_cast(layers[i].springiness) + dist(rng); - layers[i].springiness = static_cast(std::clamp(v, 0, 100)); + layers[i].springiness = static_cast(std::clamp(v, 0, 100)); } } // ---- デバッグ/鑑賞用 ---- // - friend ostream& operator<<(ostream& os, const PoyoPoyoPudding& p) { + friend std::ostream& operator<<(std::ostream& os, const PoyoPoyoPudding& p) { os << "🍮 PoyoPoyoPudding (" << p.top << " / " << kMaxLayers << " layers)\n"; - for (size_t i = p.top; i-- > 0;) { + for (std::size_t i = p.top; i-- > 0;) { const auto& L = p.layers[i]; - os << " ├─ Layer " << setw(2) << i << " | Sweet " << setw(3) - << int(L.sweetness) << " | Spring " << setw(3) << int(L.springiness) - << '\n'; + os << " ├─ Layer " << std::setw(2) << i << " | Sweet " << std::setw(3) + << int(L.sweetness) << " | Spring " << std::setw(3) + << int(L.springiness) << '\n'; } return os; } }; +#pragma once diff --git a/other/scanner.hpp b/other/scanner.hpp index 30d9841d9..2ac98c340 100644 --- a/other/scanner.hpp +++ b/other/scanner.hpp @@ -1,9 +1,18 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + /** * @brief Scanner(高速入力) */ struct Scanner { public: - explicit Scanner(FILE* fp) : fp(fp) {} + explicit Scanner(std::FILE* fp) : fp(fp) {} template void read(T& t, E&... e) { @@ -12,10 +21,10 @@ struct Scanner { } private: - static constexpr size_t line_size = 1 << 16; - static constexpr size_t int_digits = 20; + static constexpr std::size_t line_size = 1 << 16; + static constexpr std::size_t int_digits = 20; char line[line_size + 1] = {}; - FILE* fp = nullptr; + std::FILE* fp = nullptr; char* st = line; char* ed = line; @@ -24,10 +33,10 @@ struct Scanner { static inline bool is_space(char c) { return c <= ' '; } void reread() { - ptrdiff_t len = ed - st; - memmove(line, st, len); + std::ptrdiff_t len = ed - st; + std::memmove(line, st, len); char* tmp = line + len; - ed = tmp + fread(tmp, 1, line_size - len, fp); + ed = tmp + std::fread(tmp, 1, line_size - len, fp); *ed = 0; st = line; } @@ -40,37 +49,39 @@ struct Scanner { } } - template ::value, int> = 0> + template ::value, int> = 0> void read_single(T& s) { skip_space(); if (st + int_digits >= ed) reread(); bool neg = false; - if (is_signed::value && *st == '-') { + if (std::is_signed::value && *st == '-') { neg = true; ++st; } - typename make_unsigned::type y = *st++ - '0'; + typename std::make_unsigned::type y = *st++ - '0'; while (*st >= '0') { y = 10 * y + *st++ - '0'; } s = (neg ? -y : y); } - template ::value, int> = 0> + template ::value, int> = 0> void read_single(T& s) { s = ""; skip_space(); while (true) { char* base = st; while (*st && !is_space(*st)) ++st; - s += string(base, st); + s += std::string(base, st); if (st != ed) return; reread(); } } template - void read_single(vector& s) { + void read_single(std::vector& s) { for (auto& d : s) read(d); } }; +#pragma once diff --git a/other/static-point-add-rectangle-sum.hpp b/other/static-point-add-rectangle-sum.hpp index 17314fa1d..d3858d79a 100644 --- a/other/static-point-add-rectangle-sum.hpp +++ b/other/static-point-add-rectangle-sum.hpp @@ -1,10 +1,18 @@ +#pragma once + +#include +#include +#include +#include +#include + #include "../structure/others/binary-indexed-tree.hpp" template struct StaticPointAddRectangleSum { using BIT = BinaryIndexedTree; - static_assert(is_integral::value, + static_assert(std::is_integral::value, "template parameter T must be integral type"); struct Point { @@ -16,8 +24,8 @@ struct StaticPointAddRectangleSum { T l, d, r, u; }; - vector points; - vector queries; + std::vector points; + std::vector queries; StaticPointAddRectangleSum() = default; @@ -33,16 +41,16 @@ struct StaticPointAddRectangleSum { queries.emplace_back(Query{l, d, r, u}); } - vector calculate_queries() { + std::vector calculate_queries() { int n = (int)points.size(); int q = (int)queries.size(); - vector ans(q); + std::vector ans(q); if (points.empty() or queries.empty()) { return ans; } - sort(points.begin(), points.end(), - [](const Point& a, const Point& b) { return a.y < b.y; }); - vector ys; + std::sort(points.begin(), points.end(), + [](const Point& a, const Point& b) { return a.y < b.y; }); + std::vector ys; ys.reserve(n); for (Point& p : points) { if (ys.empty() or ys.back() != p.y) ys.emplace_back(p.y); @@ -56,7 +64,7 @@ struct StaticPointAddRectangleSum { bool type; int idx; }; - vector qs; + std::vector qs; qs.reserve(q + q); for (int i = 0; i < q; i++) { auto& query = queries[i]; @@ -65,10 +73,10 @@ struct StaticPointAddRectangleSum { qs.emplace_back(Q{query.l, d, u, false, i}); qs.emplace_back(Q{query.r, d, u, true, i}); } - sort(points.begin(), points.end(), - [](const Point& a, const Point& b) { return a.x < b.x; }); - sort(qs.begin(), qs.end(), - [](const Q& a, const Q& b) { return a.x < b.x; }); + std::sort(points.begin(), points.end(), + [](const Point& a, const Point& b) { return a.x < b.x; }); + std::sort(qs.begin(), qs.end(), + [](const Q& a, const Q& b) { return a.x < b.x; }); int j = 0; BIT bit(ys.size()); for (auto& query : qs) { @@ -84,3 +92,4 @@ struct StaticPointAddRectangleSum { return ans; } }; +#pragma once diff --git a/other/static-range-count-distinct.hpp b/other/static-range-count-distinct.hpp index 94afa9770..fd88119e8 100644 --- a/other/static-range-count-distinct.hpp +++ b/other/static-range-count-distinct.hpp @@ -1,18 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + #include "../structure/others/binary-indexed-tree.hpp" template struct StaticRangeCountDistinct { private: using BIT = BinaryIndexedTree; - size_t m; - vector xs; - vector > mp; - vector > qs; + std::size_t m; + std::vector xs; + std::vector > mp; + std::vector > qs; public: - explicit StaticRangeCountDistinct(const vector& vs) : xs(vs.size()) { - vector ys = vs; - sort(ys.begin(), ys.end()); + explicit StaticRangeCountDistinct(const std::vector& vs) : xs(vs.size()) { + std::vector ys = vs; + std::sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end()); m = ys.size(); for (int i = 0; i < vs.size(); i++) { @@ -26,18 +35,18 @@ struct StaticRangeCountDistinct { qs.emplace_back(l, r - 1); } - vector calclate_queries() const { + std::vector calclate_queries() const { int n = (int)xs.size(); int q = (int)qs.size(); - vector > ev(n); + std::vector > ev(n); for (int i = 0; i < q; i++) { if (qs[i].first <= qs[i].second) { ev[qs[i].second].emplace_back(i); } } - vector pre(m, -1); + std::vector pre(m, -1); BIT bit(n); - vector ans(q); + std::vector ans(q); for (int i = 0; i < n; i++) { int v = xs[i]; if (~pre[v]) bit.apply(n - pre[v] - 1, -1); @@ -50,3 +59,4 @@ struct StaticRangeCountDistinct { return ans; } }; +#pragma once diff --git a/other/static-rectangle-add-point-get.hpp b/other/static-rectangle-add-point-get.hpp index 9b9e64d79..b04000e72 100644 --- a/other/static-rectangle-add-point-get.hpp +++ b/other/static-rectangle-add-point-get.hpp @@ -1,3 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + #include "../structure/others/binary-indexed-tree.hpp" template @@ -5,7 +14,7 @@ struct StaticRectangleAddPointGet { private: using BIT = BinaryIndexedTree; - static_assert(is_integral::value, + static_assert(std::is_integral::value, "template parameter T must be integral type"); struct Rectangle { @@ -17,8 +26,8 @@ struct StaticRectangleAddPointGet { T x, y; }; - vector rectangles; - vector queries; + std::vector rectangles; + std::vector queries; public: StaticRectangleAddPointGet() = default; @@ -34,20 +43,20 @@ struct StaticRectangleAddPointGet { void add_query(T x, T y) { queries.emplace_back(Query{x, y}); } - vector calculate_queries() const { + std::vector calculate_queries() const { int n = (int)rectangles.size(); int q = (int)queries.size(); - vector ans(q); + std::vector ans(q); if (rectangles.empty() or queries.empty()) { return ans; } - vector ys; + std::vector ys; ys.reserve(q); for (int i = 0; i < q; i++) { ys.emplace_back(queries[i].y); } - sort(ys.begin(), ys.end()); + std::sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end()); struct R { @@ -56,7 +65,7 @@ struct StaticRectangleAddPointGet { bool type; C w; }; - vector rs; + std::vector rs; rs.reserve(n + n); for (int i = 0; i < n; i++) { auto& rect = rectangles[i]; @@ -65,13 +74,13 @@ struct StaticRectangleAddPointGet { rs.emplace_back(R{rect.l, d, u, false, rect.w}); rs.emplace_back(R{rect.r, d, u, true, rect.w}); } - sort(rs.begin(), rs.end(), - [](const R& a, const R& b) { return a.x < b.x; }); + std::sort(rs.begin(), rs.end(), + [](const R& a, const R& b) { return a.x < b.x; }); - vector qs(q); - iota(qs.begin(), qs.end(), 0); - sort(qs.begin(), qs.end(), - [&](int a, int b) { return queries[a].x < queries[b].x; }); + std::vector qs(q); + std::iota(qs.begin(), qs.end(), 0); + std::sort(qs.begin(), qs.end(), + [&](int a, int b) { return queries[a].x < queries[b].x; }); int j = 0; BIT bit(ys.size()); @@ -92,3 +101,4 @@ struct StaticRectangleAddPointGet { return ans; } }; +#pragma once diff --git a/other/static-rectangle-add-rectangle-sum.hpp b/other/static-rectangle-add-rectangle-sum.hpp index 7a4f9c807..c8de1fdb2 100644 --- a/other/static-rectangle-add-rectangle-sum.hpp +++ b/other/static-rectangle-add-rectangle-sum.hpp @@ -1,8 +1,17 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + #include "../structure/others/binary-indexed-tree.hpp" template struct StaticRectangleAddRectangleSum { - struct Hikari : array { + struct Hikari : std::array { Hikari& operator+=(const Hikari& p) { for (int i = 0; i < 4; i++) { this->at(i) += p.at(i); @@ -13,7 +22,7 @@ struct StaticRectangleAddRectangleSum { using BIT = BinaryIndexedTree; - static_assert(is_integral::value, + static_assert(std::is_integral::value, "template parameter T must be integral type"); struct Rectangle { @@ -25,8 +34,8 @@ struct StaticRectangleAddRectangleSum { T l, d, r, u; }; - vector rectangles; - vector queries; + std::vector rectangles; + std::vector queries; StaticRectangleAddRectangleSum() = default; @@ -44,20 +53,20 @@ struct StaticRectangleAddRectangleSum { queries.emplace_back(Query{l, d, r, u}); } - vector calculate_queries() { + std::vector calculate_queries() { int n = (int)rectangles.size(); int q = (int)queries.size(); - vector ans(q); + std::vector ans(q); if (rectangles.empty() or queries.empty()) { return ans; } - vector ys; + std::vector ys; ys.reserve(n + n); for (Rectangle& p : rectangles) { ys.emplace_back(p.d); ys.emplace_back(p.u); } - sort(ys.begin(), ys.end()); + std::sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end()); struct Q { @@ -66,7 +75,7 @@ struct StaticRectangleAddRectangleSum { bool type; int idx; }; - vector rs, qs; + std::vector rs, qs; rs.reserve(n + n); qs.reserve(q + q); for (int i = 0; i < n; i++) { @@ -83,10 +92,10 @@ struct StaticRectangleAddRectangleSum { qs.emplace_back(Q{p.l, d, u, false, i}); qs.emplace_back(Q{p.r, d, u, true, i}); } - sort(rs.begin(), rs.end(), - [](const Q& a, const Q& b) { return a.x < b.x; }); - sort(qs.begin(), qs.end(), - [](const Q& a, const Q& b) { return a.x < b.x; }); + std::sort(rs.begin(), rs.end(), + [](const Q& a, const Q& b) { return a.x < b.x; }); + std::sort(qs.begin(), qs.end(), + [](const Q& a, const Q& b) { return a.x < b.x; }); int j = 0; BIT bit(ys.size()); for (auto& query : qs) { @@ -117,3 +126,4 @@ struct StaticRectangleAddRectangleSum { return ans; } }; +#pragma once diff --git a/other/timer.hpp b/other/timer.hpp index 141e39eec..09e5f66f5 100644 --- a/other/timer.hpp +++ b/other/timer.hpp @@ -1,8 +1,12 @@ -constexpr uint64_t CYCLES_PER_SEC = 2900000000; // AtCoder -// constexpr uint64_t CYCLES_PER_SEC = 3600000000; // Codeforces -// constexpr uint64_t CYCLES_PER_SEC = 2300000000; // yukicoder +#pragma once + +#include + +constexpr std::uint64_t CYCLES_PER_SEC = 2900000000; // AtCoder +// constexpr std::uint64_t CYCLES_PER_SEC = 3600000000; // Codeforces +// constexpr std::uint64_t CYCLES_PER_SEC = 2300000000; // yukicoder struct Timer { - uint64_t start; + std::uint64_t start; Timer() : start{} { reset(); } @@ -12,9 +16,10 @@ struct Timer { return (double)get_cycle() / CYCLES_PER_SEC; } - inline uint64_t get_cycle() const { + inline std::uint64_t get_cycle() const { unsigned low, high; __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); - return (((uint64_t)low) | ((uint64_t)high << 32ull)) - start; + return (((std::uint64_t)low) | ((std::uint64_t)high << 32ull)) - start; } }; +#pragma once diff --git a/scripts/self-contained-headers.txt b/scripts/self-contained-headers.txt index a6e1745d6..d09c7dab4 100644 --- a/scripts/self-contained-headers.txt +++ b/scripts/self-contained-headers.txt @@ -52,11 +52,37 @@ geometry/projection.hpp geometry/reflection.hpp geometry/segment.hpp graph/graph-template.hpp +graph/mst/boruvka.hpp +graph/mst/directed-mst.hpp +graph/mst/kruskal.hpp +graph/mst/manhattan-mst.hpp +graph/mst/prim.hpp +graph/others/cartesian-tree.hpp +graph/others/chromatic-number.hpp +graph/others/cycle-detection.hpp +graph/others/dominator-tree.hpp +graph/others/enumerate-cliques.hpp +graph/others/enumerate-triangles.hpp +graph/others/eulerian-trail.hpp +graph/others/extreme-vertex-set.hpp +graph/others/low-link.hpp +graph/others/maximum-clique.hpp +graph/others/maximum-independent-set.hpp +graph/others/minimum-steiner-tree.hpp +graph/others/namori-graph.hpp +graph/others/offline-dag-reachability.hpp +graph/others/topological-sort.hpp +graph/others/tree-decomposition-width-2.hpp graph/shortest-path/bellman-ford.hpp graph/shortest-path/bfs.hpp graph/shortest-path/dijkstra.hpp graph/shortest-path/grid-bfs.hpp graph/shortest-path/warshall-floyd.hpp +graph/tree/centroid.hpp +graph/tree/convert-rooted-tree.hpp +graph/tree/heavy-light-decomposition.hpp +graph/tree/rerooting.hpp +graph/tree/tree-diameter.hpp math/combinatorics/arbitrary-mod-int.hpp math/combinatorics/bell-number.hpp math/combinatorics/binomial-prefix-sum-query.hpp @@ -94,6 +120,7 @@ math/fft/subset-convolution.hpp math/fft/subset-zeta-moebius-transform.hpp math/fft/superset-zeta-moebius-transform-simd.hpp math/fft/superset-zeta-moebius-transform.hpp +math/matrix/binary-basis.hpp math/matrix/matrix.hpp math/matrix/square-matrix.hpp math/number-theory/convert-base.hpp @@ -115,12 +142,25 @@ math/rational/rational.hpp other/ceil-div.hpp other/chrono-timer.hpp other/compress.hpp +other/connected-grid-states.hpp other/dice.hpp +other/dynamic-point-add-rectangle-sum.hpp +other/dynamic-rectangle-add-point-get.hpp other/floor-div.hpp +other/mo-rollback.hpp +other/mo.hpp +other/offline-dynamic-connectivity.hpp other/offline-rmq.hpp +other/poyopoyo-pudding.hpp other/printer.hpp other/random-number-generator.hpp +other/scanner.hpp +other/static-point-add-rectangle-sum.hpp +other/static-range-count-distinct.hpp other/static-range-frequency.hpp +other/static-rectangle-add-point-get.hpp +other/static-rectangle-add-rectangle-sum.hpp +other/timer.hpp other/vector-pool.hpp other/xor-shift.hpp string/manacher.hpp diff --git a/test/unittest/self-contained-header-migration.test.cpp b/test/unittest/self-contained-header-migration.test.cpp index 85bac8f1d..d522a9276 100644 --- a/test/unittest/self-contained-header-migration.test.cpp +++ b/test/unittest/self-contained-header-migration.test.cpp @@ -6,6 +6,43 @@ #include #include +#include "../../graph/mst/boruvka.hpp" +#include "../../graph/mst/manhattan-mst.hpp" +#include "../../graph/others/cartesian-tree.hpp" +#include "../../graph/others/chromatic-number.hpp" +#include "../../graph/others/cycle-detection.hpp" +#include "../../graph/others/dominator-tree.hpp" +#include "../../graph/others/enumerate-cliques.hpp" +#include "../../graph/others/enumerate-triangles.hpp" +#include "../../graph/others/eulerian-trail.hpp" +#include "../../graph/others/extreme-vertex-set.hpp" +#include "../../graph/others/low-link.hpp" +#include "../../graph/others/maximum-clique.hpp" +#include "../../graph/others/maximum-independent-set.hpp" +#include "../../graph/others/minimum-steiner-tree.hpp" +#include "../../graph/others/namori-graph.hpp" +#include "../../graph/others/offline-dag-reachability.hpp" +#include "../../graph/others/topological-sort.hpp" +#include "../../graph/others/tree-decomposition-width-2.hpp" +#include "../../graph/tree/centroid.hpp" +#include "../../graph/tree/convert-rooted-tree.hpp" +#include "../../graph/tree/heavy-light-decomposition.hpp" +#include "../../graph/tree/rerooting.hpp" +#include "../../graph/tree/tree-diameter.hpp" +#include "../../math/matrix/binary-basis.hpp" +#include "../../other/connected-grid-states.hpp" +#include "../../other/dynamic-point-add-rectangle-sum.hpp" +#include "../../other/dynamic-rectangle-add-point-get.hpp" +#include "../../other/mo-rollback.hpp" +#include "../../other/mo.hpp" +#include "../../other/offline-dynamic-connectivity.hpp" +#include "../../other/poyopoyo-pudding.hpp" +#include "../../other/scanner.hpp" +#include "../../other/static-point-add-rectangle-sum.hpp" +#include "../../other/static-range-count-distinct.hpp" +#include "../../other/static-rectangle-add-point-get.hpp" +#include "../../other/static-rectangle-add-rectangle-sum.hpp" +#include "../../other/timer.hpp" #include "../../dp/cumulative-sum-2d.hpp" #include "../../dp/cumulative-sum.hpp" #include "../../dp/divide-and-conquer-optimization.hpp" @@ -254,6 +291,20 @@ int main() { assert(distances[0][1] == 1); std::vector grid{"S.", ".#"}; assert(grid_bfs(grid, 'S')[0][1] == 1); + Graph dag(3); + dag.add_directed_edge(0, 1); + dag.add_directed_edge(1, 2); + assert(topological_sort(dag).size() == 3); + + BinaryBasis binary_basis; + assert(binary_basis.add(1) && binary_basis.add(2)); + assert(binary_basis.check(3) && binary_basis.size() == 2); + assert(cartesian_tree(std::vector{3, 1, 2})[0] == 1); + StaticRangeCountDistinct distinct({1, 2, 1, 3}); + distinct.add_query(0, 4); + assert(distinct.calclate_queries()[0] == 3); + PoyoPoyoPudding pudding; + assert(pudding.addLayer(50, 50) && pudding.eatTop()); using geometry::Circle; using geometry::Line; From 9732ad400b67c896c90f5c5a6f25c0a0f1fb1135 Mon Sep 17 00:00:00 2001 From: ei1333 Date: Mon, 10 Aug 2026 07:51:11 +0000 Subject: [PATCH 07/16] Migrate connectivity, FPS, and string headers --- SELF_CONTAINED_HEADER_MIGRATION.md | 4 +- .../bi-connected-components.hpp | 13 ++-- .../incremental-bridge-connectivity.hpp | 17 +++-- .../strongly-connected-components.hpp | 24 ++++--- .../three-edge-connected-components.hpp | 27 ++++---- .../two-edge-connected-components.hpp | 6 +- graph/others/block-cut-tree.hpp | 11 ++-- math/fps/bell.hpp | 4 ++ math/fps/berlekamp-massey.hpp | 6 +- math/fps/bernoulli.hpp | 3 + math/fps/binomial-prefix-sum.hpp | 31 +++++---- math/fps/coeff-of-rational-function.hpp | 6 +- .../composition-of-formal-power-series.hpp | 66 +++++++++++-------- ...itional-inverse-of-formal-power-series.hpp | 11 +++- math/fps/count-subset-sum.hpp | 9 ++- math/fps/enumerate-coefficients-of-powers.hpp | 12 +++- math/fps/eulerian.hpp | 7 +- math/fps/formal-power-series-friendly-ntt.hpp | 59 ++++++++++------- math/fps/formal-power-series.hpp | 36 ++++++---- ...th-term-of-linearly-recurrent-sequence.hpp | 8 ++- math/fps/multipoint-evaluation.hpp | 3 + math/fps/partition.hpp | 3 + math/fps/polynomial-interpolation.hpp | 8 ++- math/fps/sparse-matrix.hpp | 20 ++++-- math/fps/stirling-first.hpp | 3 + math/fps/stirling-second.hpp | 4 ++ math/fps/subproduct-tree.hpp | 8 ++- scripts/self-contained-headers.txt | 40 +++++++++++ string/aho-corasick.hpp | 26 +++++--- string/lcp-array.hpp | 9 ++- string/longest-common-substring.hpp | 20 ++++-- string/palindromic-tree.hpp | 38 ++++++----- string/rolling-hash.hpp | 45 ++++++++----- string/suffix-array.hpp | 63 +++++++++++------- string/wildcard-pattern-matching.hpp | 10 ++- structure/segment-tree/dual-segment-tree.hpp | 7 +- structure/segment-tree/lazy-segment-tree.hpp | 25 ++++--- .../segment-tree/persistent-segment-tree.hpp | 11 +++- ...ange-linear-add-range-min-segment-tree.hpp | 22 +++++-- structure/segment-tree/range-tree.hpp | 25 ++++--- structure/segment-tree/segment-tree-beats.hpp | 15 +++-- structure/trie/trie.hpp | 28 +++++--- .../self-contained-header-migration.test.cpp | 38 +++++++++++ 43 files changed, 579 insertions(+), 252 deletions(-) diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index 11d0cb18b..e6f40acc8 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -22,7 +22,7 @@ | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 200 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 240 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -132,6 +132,8 @@ g++ -std=c++17 -fsyntax-only -x c++ -include ./path/to/header.hpp /dev/null | 2026-08-10 | `math/number-theory/` の4ヘッダー、`structure/class/` の3ヘッダー、`other/` の2ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `graph/others/` の16ヘッダー、`graph/mst/` の5ヘッダー、`graph/tree/` の6ヘッダー | 標準 include と `std::` 修飾 | | 2026-08-10 | `other/` の14ヘッダー、`math/matrix/binary-basis.hpp` | 標準 include と `std::` 修飾 | +| 2026-08-10 | `graph/connected-components/` の5ヘッダー、`graph/others/block-cut-tree.hpp`、`math/fps/` の20ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `string/` の7ヘッダー、`structure/segment-tree/` の6ヘッダー、`structure/trie/trie.hpp` | 標準 include と `std::` 修飾 | ## 次の候補 diff --git a/graph/connected-components/bi-connected-components.hpp b/graph/connected-components/bi-connected-components.hpp index 89cbb7ea5..97ac4bb7e 100644 --- a/graph/connected-components/bi-connected-components.hpp +++ b/graph/connected-components/bi-connected-components.hpp @@ -1,3 +1,7 @@ +#pragma once + +#include + #include "../graph-template.hpp" #include "../others/low-link.hpp" @@ -9,7 +13,7 @@ struct BiConnectedComponents : LowLink { using LowLink::ord; using LowLink::low; - vector > > bc; + std::vector > > bc; void build() override { LowLink::build(); @@ -22,14 +26,14 @@ struct BiConnectedComponents : LowLink { explicit BiConnectedComponents(const Graph& g) : Graph(g) {} private: - vector used; - vector > tmp; + std::vector used; + std::vector > tmp; void dfs(int idx, int par) { used[idx] = true; bool beet = false; for (auto& to : g[idx]) { - if (to == par && !exchange(beet, true)) continue; + if (to == par && !std::exchange(beet, true)) continue; if (!used[to] || ord[to] < ord[idx]) { tmp.emplace_back(to); } @@ -48,3 +52,4 @@ struct BiConnectedComponents : LowLink { } } }; +#pragma once diff --git a/graph/connected-components/incremental-bridge-connectivity.hpp b/graph/connected-components/incremental-bridge-connectivity.hpp index d82c44025..9de8ad006 100644 --- a/graph/connected-components/incremental-bridge-connectivity.hpp +++ b/graph/connected-components/incremental-bridge-connectivity.hpp @@ -1,25 +1,30 @@ #pragma once +#include +#include +#include +#include + #include "../../structure/union-find/union-find.hpp" struct IncrementalBridgeConnectivity { private: UnionFind cc, bcc; - vector bbf; - size_t bridge; + std::vector bbf; + std::size_t bridge; int size() { return bbf.size(); } int par(int x) { return bbf[x] == size() ? size() : bcc.find(bbf[x]); } int lca(int x, int y) { - unordered_set used; + std::unordered_set used; for (;;) { if (x != size()) { if (!used.insert(x).second) return x; x = par(x); } - swap(x, y); + std::swap(x, y); } } @@ -51,7 +56,7 @@ struct IncrementalBridgeConnectivity { int find(int k) { return bcc.find(k); } - size_t bridge_size() const { return bridge; } + std::size_t bridge_size() const { return bridge; } void add_edge(int x, int y) { x = bcc.find(x); @@ -61,7 +66,7 @@ struct IncrementalBridgeConnectivity { compress(x, w); compress(y, w); } else { - if (cc.size(x) > cc.size(y)) swap(x, y); + if (cc.size(x) > cc.size(y)) std::swap(x, y); link(x, y); cc.unite(x, y); ++bridge; diff --git a/graph/connected-components/strongly-connected-components.hpp b/graph/connected-components/strongly-connected-components.hpp index 076c20216..83b9bd9c9 100644 --- a/graph/connected-components/strongly-connected-components.hpp +++ b/graph/connected-components/strongly-connected-components.hpp @@ -1,5 +1,11 @@ #pragma once +#include +#include +#include +#include +#include + #include "../graph-template.hpp" template @@ -7,26 +13,26 @@ struct StronglyConnectedComponents : Graph { public: using Graph::Graph; using Graph::g; - vector comp; + std::vector comp; Graph dag; - vector > group; + std::vector > group; void build() { rg = Graph(g.size()); - for (size_t i = 0; i < g.size(); i++) { + for (std::size_t i = 0; i < g.size(); i++) { for (auto& e : g[i]) { rg.add_directed_edge(e.to, e.from, e.cost); } } comp.assign(g.size(), -1); used.assign(g.size(), 0); - for (size_t i = 0; i < g.size(); i++) dfs(i); - reverse(begin(order), end(order)); + for (std::size_t i = 0; i < g.size(); i++) dfs(i); + std::reverse(std::begin(order), std::end(order)); int ptr = 0; for (int i : order) if (comp[i] == -1) rdfs(i, ptr), ptr++; dag = Graph(ptr); - for (size_t i = 0; i < g.size(); i++) { + for (std::size_t i = 0; i < g.size(); i++) { for (auto& e : g[i]) { int x = comp[e.from], y = comp[e.to]; if (x == y) continue; @@ -34,7 +40,7 @@ struct StronglyConnectedComponents : Graph { } } group.resize(ptr); - for (size_t i = 0; i < g.size(); i++) { + for (std::size_t i = 0; i < g.size(); i++) { group[comp[i]].emplace_back(i); } } @@ -42,11 +48,11 @@ struct StronglyConnectedComponents : Graph { int operator[](int k) const { return comp[k]; } private: - vector order, used; + std::vector order, used; Graph rg; void dfs(int idx) { - if (exchange(used[idx], true)) return; + if (std::exchange(used[idx], true)) return; for (auto& to : g[idx]) dfs(to); order.push_back(idx); } diff --git a/graph/connected-components/three-edge-connected-components.hpp b/graph/connected-components/three-edge-connected-components.hpp index 5470531c7..90058cf61 100644 --- a/graph/connected-components/three-edge-connected-components.hpp +++ b/graph/connected-components/three-edge-connected-components.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../graph-template.hpp" #include "incremental-bridge-connectivity.hpp" @@ -8,7 +11,7 @@ struct ThreeEdgeConnectedComponents : Graph { public: using Graph::Graph; using Graph::g; - vector > group; + std::vector > group; void build() { uf = UnionFind(g.size()); @@ -18,25 +21,25 @@ struct ThreeEdgeConnectedComponents : Graph { out.assign(g.size(), 0); deg.assign(g.size(), 0); low.assign(g.size(), g.size()); - for (size_t from = 0; from < g.size(); from++) { + for (std::size_t from = 0; from < g.size(); from++) { for (auto& to : g[from]) { if ((T)from < to) bcc.add_edge(from, to); } } int cnt = 0; - for (size_t i = 0; i < g.size(); i++) { + for (std::size_t i = 0; i < g.size(); i++) { if (used[i]) continue; - vector tmp; + std::vector tmp; dfs(i, -1, tmp, cnt); cnt++; } - vector id(g.size(), -1); + std::vector id(g.size(), -1); cnt = 0; - for (size_t i = 0; i < g.size(); i++) { + for (std::size_t i = 0; i < g.size(); i++) { if (id[uf.find(i)] == -1) id[uf.find(i)] = cnt++; } group.resize(cnt); - for (size_t i = 0; i < g.size(); i++) { + for (std::size_t i = 0; i < g.size(); i++) { group[id[uf.find(i)]].emplace_back(i); } } @@ -44,12 +47,12 @@ struct ThreeEdgeConnectedComponents : Graph { int operator[](const int& k) { return uf.find(k); } private: - vector used; - vector in, out, low, deg; + std::vector used; + std::vector in, out, low, deg; IncrementalBridgeConnectivity bcc; UnionFind uf; - void absorb(vector& path, int v, int w = -1) { + void absorb(std::vector& path, int v, int w = -1) { while (!path.empty()) { int x = path.back(); if (w != -1 && (in[x] > in[w] or in[w] >= out[x])) break; @@ -59,7 +62,7 @@ struct ThreeEdgeConnectedComponents : Graph { } } - void dfs(int idx, int p, vector& path, int& k) { + void dfs(int idx, int p, std::vector& path, int& k) { used[idx] = 1; in[idx] = low[idx] = k++; for (auto& to : g[idx]) { @@ -80,7 +83,7 @@ struct ThreeEdgeConnectedComponents : Graph { absorb(path, idx, to); } } else { - vector ps; + std::vector ps; dfs(to, idx, ps, k); if (deg[to] == 2) ps.pop_back(); if (low[to] < low[idx]) { diff --git a/graph/connected-components/two-edge-connected-components.hpp b/graph/connected-components/two-edge-connected-components.hpp index 67050e661..eff02ff90 100644 --- a/graph/connected-components/two-edge-connected-components.hpp +++ b/graph/connected-components/two-edge-connected-components.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "../graph-template.hpp" #include "../others/low-link.hpp" @@ -12,9 +14,9 @@ struct TwoEdgeConnectedComponents : LowLink { using LowLink::low; using LowLink::bridge; - vector comp; + std::vector comp; Graph tree; - vector > group; + std::vector > group; int operator[](const int& k) const { return comp[k]; } diff --git a/graph/others/block-cut-tree.hpp b/graph/others/block-cut-tree.hpp index debd83858..184a4c4ab 100644 --- a/graph/others/block-cut-tree.hpp +++ b/graph/others/block-cut-tree.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../connected-components/bi-connected-components.hpp" #include "../graph-template.hpp" @@ -15,8 +18,8 @@ struct BlockCutTree : BiConnectedComponents { using BiConnectedComponents::articulation; using BiConnectedComponents::bc; - vector rev; - vector > group; + std::vector rev; + std::vector > group; Graph tree; explicit BlockCutTree(const Graph& g) : Graph(g) {} @@ -30,13 +33,13 @@ struct BlockCutTree : BiConnectedComponents { for (auto& idx : articulation) { rev[idx] = ptr++; } - vector last(ptr, -1); + std::vector last(ptr, -1); tree = Graph(ptr); for (int i = 0; i < (int)bc.size(); i++) { for (auto& e : bc[i]) { for (auto& ver : {e.from, e.to}) { if (rev[ver] >= (int)bc.size()) { - if (exchange(last[rev[ver]], i) != i) { + if (std::exchange(last[rev[ver]], i) != i) { tree.add_edge(rev[ver], i, e.cost); } } else { diff --git a/math/fps/bell.hpp b/math/fps/bell.hpp index a4c0f29a6..ea2832e4f 100644 --- a/math/fps/bell.hpp +++ b/math/fps/bell.hpp @@ -1,3 +1,6 @@ +#pragma once + +#include /** * @brief Bell(ベル数) * @@ -16,3 +19,4 @@ FPS bell(int N) { } return ret; } +#pragma once diff --git a/math/fps/berlekamp-massey.hpp b/math/fps/berlekamp-massey.hpp index 70a527bb9..2b7bb1127 100644 --- a/math/fps/berlekamp-massey.hpp +++ b/math/fps/berlekamp-massey.hpp @@ -1,3 +1,6 @@ +#pragma once + +#include /** * @brief Berlekamp Massey */ @@ -16,7 +19,7 @@ FPS berlekamp_massey(const FPS& s) { Mint freq = x / y; if (l < m) { auto tmp = c; - c.insert(begin(c), m - l, Mint(0)); + c.insert(std::begin(c), m - l, Mint(0)); for (int i = 0; i < m; i++) c[m - 1 - i] -= freq * b[m - 1 - i]; b = tmp; y = x; @@ -26,3 +29,4 @@ FPS berlekamp_massey(const FPS& s) { } return c; } +#pragma once diff --git a/math/fps/bernoulli.hpp b/math/fps/bernoulli.hpp index 05de05629..89555ec97 100644 --- a/math/fps/bernoulli.hpp +++ b/math/fps/bernoulli.hpp @@ -1,3 +1,5 @@ +#pragma once + /** * @brief Bernoulli(ベルヌーイ数) */ @@ -16,3 +18,4 @@ FPS bernoulli(int N) { } return poly; } +#pragma once diff --git a/math/fps/binomial-prefix-sum.hpp b/math/fps/binomial-prefix-sum.hpp index 8feeebb9c..f11860b5d 100644 --- a/math/fps/binomial-prefix-sum.hpp +++ b/math/fps/binomial-prefix-sum.hpp @@ -1,12 +1,17 @@ #pragma once +#include +#include +#include + #include "multipoint-evaluation.hpp" /** * @brief Binomial Coefficient Prefix Sum */ template