diff --git a/SELF_CONTAINED_HEADER_MIGRATION.md b/SELF_CONTAINED_HEADER_MIGRATION.md index b5cf91f66..35ccc9511 100644 --- a/SELF_CONTAINED_HEADER_MIGRATION.md +++ b/SELF_CONTAINED_HEADER_MIGRATION.md @@ -15,14 +15,18 @@ - `test/verify/*.test.cpp` が `template/template.hpp` に依存しない - verify に通常の clang-format include sorting を適用できる +`template/template.hpp` は競技用テンプレートとして標準ライブラリの一括 +import と別名を意図的に提供する集約ヘッダーのため、自己完結ヘッダーの一覧から +除外している。 + ## 現在の進捗 -2026-08-04 時点の進捗は次のとおり。 +2026-08-10 時点の進捗は次のとおり。 | 項目 | 状態 | 件数 | | ----------------------------------------- | -------- | ---- | | リポジトリ内の `.hpp` | 調査済み | 320 | -| 自己完結化して継続検査しているヘッダー | 移行済み | 20 | +| 自己完結化して継続検査しているヘッダー | 移行済み | 319 | | `template/template.hpp` に依存する verify | 移行待ち | 243 | 移行済みヘッダーの正本は @@ -94,32 +98,54 @@ 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::` 修飾 | +| 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::` 修飾 | +| 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::` 修飾 | +| 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::` 修飾 | +| 2026-08-10 | `graph/flow/` の2ヘッダー、`graph/shortest-path/` の7ヘッダー、`graph/tree/` の9ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `structure/` の20ヘッダー、`other/` の2ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `geometry/template.hpp`、`graph/flow/` の10ヘッダー、`graph/mst/` の1ヘッダー、`graph/others/` の2ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | `structure/bbst/` の10ヘッダー、`structure/dynamic-tree/` の13ヘッダー、`structure/wavelet/` の2ヘッダー | 標準 include と `std::` 修飾 | +| 2026-08-10 | 移行済みヘッダー34件 | 未修飾標準名と include guard を修正 | ## 次の候補 -次の候補として、プロジェクト内ヘッダーへの依存がない -`structure/others/slope-trick.hpp` と -`structure/others/generalized-slope-trick.hpp` を検討する。その後も依存関係の葉に -近いヘッダーから進め、1コミットの変更範囲を小さく保つ。 +ヘッダーの自己完結化は `template/template.hpp` を除いて完了している。 +次は対応する verify から `template/template.hpp` 依存を段階的に削除し、 +`scripts/verify-template-include-allowlist.txt` の例外を減らす。 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/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/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-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/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/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/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-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/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/geometry/template.hpp b/geometry/template.hpp index 47cfc0ab0..0e94535f9 100644 --- a/geometry/template.hpp +++ b/geometry/template.hpp @@ -1,28 +1,41 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using Real = double; -using Point = complex; -const Real EPS = 1e-8, PI = acos(-1); +using Point = std::complex; +const Real EPS = 1e-8, PI = std::acos(-1); -inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; } +inline bool eq(Real a, Real b) { return std::fabs(b - a) < EPS; } 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); } -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, Point& p) { - return os << fixed << setprecision(10) << p.real() << " " << p.imag(); +std::ostream& operator<<(std::ostream& os, Point& p) { + return os << std::fixed << std::setprecision(10) << p.real() << " " + << p.imag(); } // rotate point p counterclockwise by theta rad Point rotate(Real theta, const Point& p) { - return Point(cos(theta) * p.real() - sin(theta) * p.imag(), - sin(theta) * p.real() + cos(theta) * p.imag()); + return Point(std::cos(theta) * p.real() - std::sin(theta) * p.imag(), + std::sin(theta) * p.real() + std::cos(theta) * p.imag()); } Real radian_to_degree(Real r) { return (r * 180.0 / PI); } @@ -32,10 +45,11 @@ Real degree_to_radian(Real d) { return (d * PI / 180.0); } // smaller angle of the a-b-c Real get_angle(const Point& a, const Point& b, const Point& c) { const Point v(b - a), w(c - b); - Real alpha = atan2(v.imag(), v.real()), beta = atan2(w.imag(), w.real()); - if (alpha > beta) swap(alpha, beta); + Real alpha = std::atan2(v.imag(), v.real()), + beta = std::atan2(w.imag(), w.real()); + if (alpha > beta) std::swap(alpha, beta); Real theta = (beta - alpha); - return min(theta, 2 * acos(-1) - theta); + return std::min(theta, 2 * std::acos(-1) - theta); } namespace std { @@ -61,11 +75,13 @@ struct Line { a = Point(0, C / B), b = Point(C / A, 0); } - friend ostream& operator<<(ostream& os, Line& p) { + friend std::ostream& operator<<(std::ostream& os, Line& p) { return os << p.a << " to " << p.b; } - friend istream& operator>>(istream& is, Line& a) { return is >> a.a >> a.b; } + friend std::istream& operator>>(std::istream& is, Line& a) { + return is >> a.a >> a.b; + } }; struct Segment : Line { @@ -83,18 +99,18 @@ struct Circle { Circle(Point p, Real r) : p(p), r(r) {} }; -using Points = vector; -using Polygon = vector; -using Segments = vector; -using Lines = vector; -using Circles = vector; +using Points = std::vector; +using Polygon = std::vector; +using Segments = std::vector; +using Lines = std::vector; +using Circles = std::vector; 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); } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C @@ -134,12 +150,12 @@ Point reflection(const Line& l, const Point& p) { } bool intersect(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; } bool intersect(const Line& l, const Line& m) { - return abs(cross(l.b - l.a, m.b - m.a)) > EPS || - abs(cross(l.b - l.a, m.b - l.a)) < EPS; + return std::abs(cross(l.b - l.a, m.b - m.a)) > EPS || + std::abs(cross(l.b - l.a, m.b - l.a)) < EPS; } bool intersect(const Segment& s, const Point& p) { @@ -157,7 +173,7 @@ bool intersect(const Circle& c, const Line& l) { } bool intersect(const Circle& c, const Point& p) { - return abs(abs(p - c.p) - c.r) < EPS; + return std::abs(std::abs(p - c.p) - c.r) < EPS; } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B @@ -168,7 +184,7 @@ bool intersect(const Segment& s, const Segment& t) { int intersect(const Circle& c, const Segment& l) { if (norm(projection(l, c.p) - c.p) - c.r * c.r > EPS) return 0; - auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b); + auto d1 = std::abs(c.p - l.a), d2 = std::abs(c.p - l.b); if (d1 < c.r + EPS && d2 < c.r + EPS) return 0; if (d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS) return 1; @@ -179,8 +195,8 @@ int intersect(const Circle& c, const Segment& l) { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp int intersect(Circle c1, Circle c2) { - if (c1.r < c2.r) swap(c1, c2); - Real d = abs(c1.p - c2.p); + if (c1.r < c2.r) std::swap(c1, c2); + Real d = std::abs(c1.p - c2.p); if (c1.r + c2.r < d) return 4; if (eq(c1.r + c2.r, d)) return 3; if (c1.r - c2.r < d) return 2; @@ -188,10 +204,10 @@ int intersect(Circle c1, Circle c2) { return 0; } -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); } Real distance(const Line& l, const Point& p) { - return abs(p - projection(l, p)); + return std::abs(p - projection(l, p)); } Real distance(const Line& l, const Line& m) { @@ -200,26 +216,26 @@ Real distance(const Line& l, const Line& m) { Real distance(const Segment& s, const Point& p) { Point r = projection(s, p); - if (intersect(s, r)) return abs(r - p); - return min(abs(s.a - p), abs(s.b - p)); + if (intersect(s, r)) return std::abs(r - p); + return std::min(std::abs(s.a - p), std::abs(s.b - p)); } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D Real distance(const Segment& a, const Segment& b) { if (intersect(a, b)) return 0; - return min( + return std::min( {distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)}); } Real distance(const Line& l, const Segment& s) { if (intersect(l, s)) return 0; - return min(distance(l, s.a), distance(l, s.b)); + return std::min(distance(l, s.a), distance(l, s.b)); } Point crosspoint(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 (eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a; + if (eq(std::abs(A), 0.0) && eq(std::abs(B), 0.0)) return m.a; return m.a + (m.b - m.a) * B / A; } @@ -229,15 +245,15 @@ Point crosspoint(const Segment& l, const Segment& m) { } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D -pair crosspoint(const Circle& c, const Line l) { +std::pair crosspoint(const Circle& c, const Line l) { Point pr = projection(l, c.p); - Point e = (l.b - l.a) / abs(l.b - l.a); + Point e = (l.b - l.a) / std::abs(l.b - l.a); if (eq(distance(l, c.p), c.r)) return {pr, pr}; - double base = sqrt(c.r * c.r - norm(pr - c.p)); + double base = std::sqrt(c.r * c.r - norm(pr - c.p)); return {pr - e * base, pr + e * base}; } -pair crosspoint(const Circle& c, const Segment& l) { +std::pair crosspoint(const Circle& c, const Segment& l) { Line aa = Line(l.a, l.b); if (intersect(c, l) == 2) return crosspoint(c, aa); auto ret = crosspoint(c, aa); @@ -249,36 +265,36 @@ pair crosspoint(const Circle& c, const Segment& l) { } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E -pair crosspoint(const Circle& c1, const Circle& c2) { - Real d = abs(c1.p - c2.p); - Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d)); - Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real()); - Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r); - Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r); +std::pair crosspoint(const Circle& c1, const Circle& c2) { + Real d = std::abs(c1.p - c2.p); + Real a = std::acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d)); + Real t = std::atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real()); + Point p1 = c1.p + Point(std::cos(t + a) * c1.r, std::sin(t + a) * c1.r); + Point p2 = c1.p + Point(std::cos(t - a) * c1.r, std::sin(t - a) * c1.r); return {p1, p2}; } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F // tangent of circle c through point p -pair tangent(const Circle& c1, const Point& p2) { - return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r))); +std::pair tangent(const Circle& c1, const Point& p2) { + return crosspoint(c1, Circle(p2, std::sqrt(norm(c1.p - p2) - c1.r * c1.r))); } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G // common tangent of circles c1 and c2 Lines tangent(Circle c1, Circle c2) { Lines ret; - if (c1.r < c2.r) swap(c1, c2); + if (c1.r < c2.r) std::swap(c1, c2); Real g = norm(c1.p - c2.p); if (eq(g, 0)) return ret; - Point u = (c2.p - c1.p) / sqrt(g); + Point u = (c2.p - c1.p) / std::sqrt(g); Point v = rotate(PI * 0.5, u); for (int s : {-1, 1}) { - Real h = (c1.r + s * c2.r) / sqrt(g); + Real h = (c1.r + s * c2.r) / std::sqrt(g); if (eq(1 - h * h, 0)) { ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r); } else if (1 - h * h > 0) { - Point uu = u * h, vv = v * sqrt(1 - h * h); + Point uu = u * h, vv = v * std::sqrt(1 - h * h); ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s); ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s); } @@ -299,8 +315,8 @@ bool is_convex(const Polygon& p) { Polygon convex_hull(Polygon& p) { int n = (int)p.size(), k = 0; if (n <= 2) return p; - sort(p.begin(), p.end()); - vector ch(2 * n); + std::sort(p.begin(), p.end()); + std::vector ch(2 * n); for (int i = 0; i < n; ch[k++] = p[i++]) { while (k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS) --k; } @@ -318,7 +334,7 @@ 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 (a.imag() > b.imag()) swap(a, b); + if (a.imag() > b.imag()) std::swap(a, b); if (a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in; if (cross(a, b) == 0 && dot(a, b) <= 0) return ON; } @@ -355,18 +371,18 @@ int convex_contains(const Polygon& Q, const Point& p) { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033 // deduplication of line segments -void merge_segments(vector& segs) { +void merge_segments(std::vector& segs) { auto merge_if_able = [](Segment& s1, const Segment& s2) { - if (abs(cross(s1.b - s1.a, s2.b - s2.a)) > EPS) return false; + if (std::abs(cross(s1.b - s1.a, s2.b - s2.a)) > EPS) return false; if (ccw(s1.a, s2.a, s1.b) == 1 || ccw(s1.a, s2.a, s1.b) == -1) return false; if (ccw(s1.a, s1.b, s2.a) == -2 || ccw(s2.a, s2.b, s1.a) == -2) return false; - s1 = Segment(min(s1.a, s2.a), max(s1.b, s2.b)); + s1 = Segment(std::min(s1.a, s2.a), std::max(s1.b, s2.b)); return true; }; for (int i = 0; i < segs.size(); i++) { - if (segs[i].b < segs[i].a) swap(segs[i].a, segs[i].b); + if (segs[i].b < segs[i].a) std::swap(segs[i].a, segs[i].b); } for (int i = 0; i < segs.size(); i++) { for (int j = i + 1; j < segs.size(); j++) { @@ -380,9 +396,9 @@ void merge_segments(vector& segs) { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033 // construct a graph with the vertex of the intersection of any two line // segments -vector > segment_arrangement(vector& segs, - vector& ps) { - vector > g; +std::vector > segment_arrangement(std::vector& segs, + std::vector& ps) { + std::vector > g; int N = (int)segs.size(); for (int i = 0; i < N; i++) { ps.emplace_back(segs[i].a); @@ -396,13 +412,13 @@ vector > segment_arrangement(vector& segs, } } } - sort(begin(ps), end(ps)); - ps.erase(unique(begin(ps), end(ps)), end(ps)); + std::sort(std::begin(ps), std::end(ps)); + ps.erase(std::unique(std::begin(ps), std::end(ps)), std::end(ps)); int M = (int)ps.size(); g.resize(M); for (int i = 0; i < N; i++) { - vector vec; + std::vector vec; for (int j = 0; j < M; j++) { if (intersect(segs[i], ps[j])) { vec.emplace_back(j); @@ -442,16 +458,16 @@ Real area(const Polygon& p) { // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_H Real area(const Polygon& p, const Circle& c) { if (p.size() < 3) return 0.0; - function cross_area = + std::function cross_area = [&](const Circle& c, const Point& a, const Point& b) { Point va = c.p - a, vb = c.p - b; Real f = cross(va, vb), ret = 0.0; if (eq(f, 0.0)) return ret; - if (max(abs(va), abs(vb)) < c.r + EPS) return f; + if (std::max(std::abs(va), std::abs(vb)) < c.r + EPS) return f; if (distance(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va)); auto u = crosspoint(c, Segment(a, b)); - vector tot{a, u.first, u.second, b}; + std::vector tot{a, u.first, u.second, b}; for (int i = 0; i + 1 < tot.size(); i++) { ret += cross_area(c, tot[i], tot[i + 1]); } @@ -489,34 +505,34 @@ Real convex_diameter(const Polygon& p) { maxj = j; } } while (i != is || j != js); - return sqrt(maxdis); + return std::sqrt(maxdis); } // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_5_A Real closest_pair(Points ps) { if (ps.size() <= 1) throw(0); - sort(begin(ps), end(ps)); + std::sort(std::begin(ps), std::end(ps)); auto compare_y = [&](const Point& a, const Point& b) { - return imag(a) < imag(b); + return std::imag(a) < std::imag(b); }; - vector beet(ps.size()); + std::vector beet(ps.size()); const Real INF = 1e18; - function rec = [&](int left, int right) { + std::function rec = [&](int left, int right) { if (right - left <= 1) return INF; int mid = (left + right) >> 1; - auto x = real(ps[mid]); - auto ret = min(rec(left, mid), rec(mid, right)); - inplace_merge(begin(ps) + left, begin(ps) + mid, begin(ps) + right, - compare_y); + auto x = std::real(ps[mid]); + auto ret = std::min(rec(left, mid), rec(mid, right)); + inplace_merge(std::begin(ps) + left, std::begin(ps) + mid, + std::begin(ps) + right, compare_y); int ptr = 0; for (int i = left; i < right; i++) { - if (abs(real(ps[i]) - x) >= ret) continue; + if (std::abs(std::real(ps[i]) - x) >= ret) continue; for (int j = 0; j < ptr; j++) { auto luz = ps[i] - beet[ptr - j - 1]; - if (imag(luz) >= ret) break; - ret = min(ret, abs(luz)); + if (std::imag(luz) >= ret) break; + ret = std::min(ret, std::abs(luz)); } beet[ptr++] = ps[i]; } diff --git a/graph/connected-components/bi-connected-components.hpp b/graph/connected-components/bi-connected-components.hpp index 89cbb7ea5..acfbcc626 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); } 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/flow/bipartite-flow.hpp b/graph/flow/bipartite-flow.hpp index 58ae780c8..54203b7b1 100644 --- a/graph/flow/bipartite-flow.hpp +++ b/graph/flow/bipartite-flow.hpp @@ -1,15 +1,24 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include /** * @brief Bipartite Flow(二部グラフのフロー) * */ struct BipartiteFlow { - size_t n, m, time_stamp; - vector > g, rg; - vector match_l, match_r, dist, used, alive; + std::size_t n, m, time_stamp; + std::vector > g, rg; + std::vector match_l, match_r, dist, used, alive; bool matched; public: - explicit BipartiteFlow(size_t n, size_t m) + explicit BipartiteFlow(std::size_t n, std::size_t m) : n(n), m(m), time_stamp(0), @@ -26,7 +35,7 @@ struct BipartiteFlow { rg[v].emplace_back(u); } - vector > max_matching() { + std::vector > max_matching() { matched = true; for (;;) { build_augment_path(); @@ -37,7 +46,7 @@ struct BipartiteFlow { } if (flow == 0) break; } - vector > ret; + std::vector > ret; for (int i = 0; i < (int)n; i++) { if (match_l[i] >= 0) ret.emplace_back(i, match_l[i]); } @@ -50,12 +59,12 @@ struct BipartiteFlow { match_l[a] = -1; match_r[b] = -1; } - g[a].erase(find(begin(g[a]), end(g[a]), b)); - rg[b].erase(find(begin(rg[b]), end(rg[b]), a)); + g[a].erase(find(std::begin(g[a]), std::end(g[a]), b)); + rg[b].erase(find(std::begin(rg[b]), std::end(rg[b]), a)); } /* http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0334 */ - vector > lex_max_matching() { + std::vector > lex_max_matching() { int matching_size = (int)max_matching().size(); int dummy_size = (int)n - matching_size; BipartiteFlow aux(n, m + dummy_size); @@ -64,16 +73,16 @@ struct BipartiteFlow { for (int j = 0; j < dummy_size; j++) aux.add_edge(i, m + j); } auto es = aux.lex_left_perfect_matching(); - vector > ret; + std::vector > ret; for (auto& [a, b] : es) { if (b < (int)m) ret.emplace_back(a, b); } return ret; } - vector min_vertex_cover() { + std::vector min_vertex_cover() { auto visited = find_residual_path(); - vector ret; + std::vector ret; for (int i = 0; i < (int)(n + m); i++) { if (visited[i] ^ (i < (int)n)) { ret.emplace_back(i); @@ -83,15 +92,15 @@ struct BipartiteFlow { } /* https://atcoder.jp/contests/utpc2013/tasks/utpc2013_11 */ - vector lex_min_vertex_cover(const vector& ord) { + std::vector lex_min_vertex_cover(const std::vector& ord) { assert(ord.size() == n + m); auto res = build_risidual_graph(); - vector > r_res(n + m + 2); + std::vector > r_res(n + m + 2); for (int i = 0; i < (int)(n + m + 2); i++) { for (auto& j : res[i]) r_res[j].emplace_back(i); } - queue que; - vector visited(n + m + 2, -1); + std::queue que; + std::vector visited(n + m + 2, -1); auto expand_left = [&](int t) { if (visited[t] != -1) return; que.emplace(t); @@ -122,7 +131,7 @@ struct BipartiteFlow { }; expand_right(n + m); expand_left(n + m + 1); - vector ret; + std::vector ret; for (auto& t : ord) { if (t < (int)n) { expand_left(t); @@ -135,9 +144,9 @@ struct BipartiteFlow { return ret; } - vector max_independent_set() { + std::vector max_independent_set() { auto visited = find_residual_path(); - vector ret; + std::vector ret; for (int i = 0; i < (int)(n + m); i++) { if (visited[i] ^ (i >= (int)n)) { ret.emplace_back(i); @@ -146,7 +155,7 @@ struct BipartiteFlow { return ret; } - vector > min_edge_cover() { + std::vector > min_edge_cover() { auto es = max_matching(); for (int i = 0; i < (int)n; i++) { if (match_l[i] >= 0) { @@ -170,11 +179,11 @@ struct BipartiteFlow { } // left: [0,n), right: [n,n+m), S: n+m, T: n+m+1 - vector > build_risidual_graph() { + std::vector > build_risidual_graph() { if (!matched) max_matching(); - const size_t S = n + m; - const size_t T = n + m + 1; - vector > ris(n + m + 2); + const std::size_t S = n + m; + const std::size_t T = n + m + 1; + std::vector > ris(n + m + 2); for (int i = 0; i < (int)n; i++) { if (match_l[i] == -1) ris[S].emplace_back(i); @@ -199,10 +208,10 @@ struct BipartiteFlow { } private: - vector > lex_left_perfect_matching() { + std::vector > lex_left_perfect_matching() { auto es = max_matching(); assert(es.size() == n); - for (auto& vs : g) sort(begin(vs), end(vs)); + for (auto& vs : g) std::sort(std::begin(vs), std::end(vs)); es.clear(); for (int i = 0; i < (int)n; i++) { match_r[match_l[i]] = -1; @@ -215,10 +224,10 @@ struct BipartiteFlow { return es; } - vector find_residual_path() { + std::vector find_residual_path() { auto res = build_risidual_graph(); - queue que; - vector visited(n + m + 2); + std::queue que; + std::vector visited(n + m + 2); que.emplace(n + m); visited[n + m] = true; while (!que.empty()) { @@ -234,7 +243,7 @@ struct BipartiteFlow { } void build_augment_path() { - queue que; + std::queue que; dist.assign(g.size(), -1); for (int i = 0; i < (int)n; i++) { if (match_l[i] == -1) { diff --git a/graph/flow/bipartite-matching.hpp b/graph/flow/bipartite-matching.hpp index df118dff4..ac8a1e944 100644 --- a/graph/flow/bipartite-matching.hpp +++ b/graph/flow/bipartite-matching.hpp @@ -1,10 +1,14 @@ +#pragma once + +#include +#include /** * @brief Bipartite-Matching(二部グラフの最大マッチング) * */ struct BipartiteMatching { - vector > graph; - vector alive, used, match; + std::vector > graph; + std::vector alive, used, match; int timestamp; explicit BipartiteMatching(int n) @@ -63,7 +67,7 @@ struct BipartiteMatching { void output() const { for (int i = 0; i < (int)graph.size(); i++) { if (i < match[i]) { - cout << i << "-" << match[i] << endl; + std::cout << i << "-" << match[i] << std::endl; } } } diff --git a/graph/flow/burn-bury.hpp b/graph/flow/burn-bury.hpp index 057280b57..fa88fc895 100644 --- a/graph/flow/burn-bury.hpp +++ b/graph/flow/burn-bury.hpp @@ -1,5 +1,14 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include +#include + #include "../../structure/union-find/union-find.hpp" #include "dinic.hpp" @@ -11,14 +20,14 @@ struct BurnBury { private: using MaxFlow = Dinic; using UF = UnionFind; - using arr2 = array; - using arr4 = array; + using arr2 = std::array; + using arr4 = std::array; int n; T alpha; - vector theta; - vector > phi; - map, T> zeta; + std::vector theta; + std::vector > phi; + std::map, T> zeta; public: explicit BurnBury(int n) : n{n}, alpha{}, theta(n), phi(n) {} @@ -30,21 +39,21 @@ struct BurnBury { void add_cost(int x, T cost) { if (not minimize) cost *= -1; - int a = max(~x, x); + int a = std::max(~x, x); theta[a][x >= 0] += cost; } void add_cost(int x, int y, T cost) { assert(x != y); if (not minimize) cost *= -1; - int a = max(~x, x), b = max(~y, y); + int a = std::max(~x, x), b = std::max(~y, y); if (a < b) phi[a][b][((x >= 0) << 1) | (y >= 0)] += cost; else phi[b][a][((y >= 0) << 1) | (x >= 0)] += cost; } - void add_cost(vector xs, T cost) { + void add_cost(std::vector xs, T cost) { assert(not xs.empty()); if (xs.size() == 1) { add_cost(xs[0], cost); @@ -52,16 +61,16 @@ struct BurnBury { add_cost(xs[0], xs[1], cost); } else { int m = (int)xs.size(); - sort(xs.begin(), xs.end()); - xs.erase(unique(xs.begin(), xs.end()), xs.end()); + std::sort(xs.begin(), xs.end()); + xs.erase(std::unique(xs.begin(), xs.end()), xs.end()); assert(m == (int)xs.size()); if (not minimize) cost *= -1; zeta[xs] += cost; } } - optional > > solve() { - vector flip(2 * n, -1); + std::optional > > solve() { + std::vector flip(2 * n, -1); { UF uf(n + n); for (int i = 0; i < n; i++) { @@ -78,11 +87,11 @@ struct BurnBury { } } for (auto& [vs, c] : zeta) { - if (c > 0) return nullopt; + if (c > 0) return std::nullopt; if (c < 0) { for (int i = 1; i < (int)vs.size(); i++) { int x = vs[i - 1], y = vs[i]; - int a = max(x, ~x), b = max(y, ~y); + int a = std::max(x, ~x), b = std::max(y, ~y); if ((x >= 0) ^ (y >= 0)) { uf.unite(a, b + n); uf.unite(a + n, b); @@ -96,7 +105,7 @@ struct BurnBury { for (int i = 0; i < n; i++) { int x = uf.find(i); int y = uf.find(i + n); - if (x == y) return nullopt; + if (x == y) return std::nullopt; if (flip[x] < 0) { flip[x] = 0; flip[y] = 1; @@ -113,12 +122,12 @@ struct BurnBury { for (int i = 0; i < n; i++) { for (auto& [j, cs] : phi[i]) { if (flip[i]) { - swap(cs[0], cs[2]); - swap(cs[1], cs[3]); + std::swap(cs[0], cs[2]); + std::swap(cs[1], cs[3]); } if (flip[j]) { - swap(cs[0], cs[1]); - swap(cs[2], cs[3]); + std::swap(cs[0], cs[1]); + std::swap(cs[2], cs[3]); } T c = -cs[0] + cs[1] + cs[2] - cs[3]; alpha += cs[0]; @@ -133,7 +142,7 @@ struct BurnBury { for (int i = 0; i < n; i++) { auto& cs = theta[i]; if (flip[i]) { - swap(cs[0], cs[1]); + std::swap(cs[0], cs[1]); } if (cs[0] <= cs[1]) { alpha += cs[0]; @@ -172,11 +181,11 @@ struct BurnBury { int u = t + 1; for (auto& [vs, c] : zeta) { if (c < 0) { - if ((vs[0] >= 0) ^ flip[max(~vs[0], vs[0])]) { + if ((vs[0] >= 0) ^ flip[std::max(~vs[0], vs[0])]) { flow.add_edge(s, u, -c); - for (auto& p : vs) flow.add_edge(u, max(p, ~p), -c); + for (auto& p : vs) flow.add_edge(u, std::max(p, ~p), -c); } else { - for (auto& p : vs) flow.add_edge(max(p, ~p), u, -c); + for (auto& p : vs) flow.add_edge(std::max(p, ~p), u, -c); flow.add_edge(u, t, -c); } alpha += c; @@ -185,11 +194,11 @@ struct BurnBury { } } T ans = flow.max_flow(s, t) + alpha; - vector cut = flow.min_cut(s); + std::vector cut = flow.min_cut(s); for (int i = 0; i < n; i++) { if (flip[i]) cut[i] = 1 - cut[i]; } cut.resize(n); - return make_pair(minimize ? ans : -ans, cut); + return std::make_pair(minimize ? ans : -ans, cut); } }; diff --git a/graph/flow/dinic-capacity-scaling.hpp b/graph/flow/dinic-capacity-scaling.hpp index 10046fb28..aeba3bc73 100644 --- a/graph/flow/dinic-capacity-scaling.hpp +++ b/graph/flow/dinic-capacity-scaling.hpp @@ -1,10 +1,18 @@ +#pragma once + +#include +#include +#include +#include +#include +#include /** * @brief Dinic Capacity Scaling(最大流) * */ template struct DinicCapacityScaling { - static_assert(is_integral::value, + static_assert(std::is_integral::value, "template parameter flow_t must be integral type"); const flow_t INF; @@ -17,15 +25,15 @@ struct DinicCapacityScaling { int idx; }; - vector > graph; - vector min_cost, iter; + std::vector > graph; + std::vector min_cost, iter; flow_t max_cap; explicit DinicCapacityScaling(int V) - : INF(numeric_limits::max()), graph(V), max_cap(0) {} + : INF(std::numeric_limits::max()), graph(V), max_cap(0) {} void add_edge(int from, int to, flow_t cap, int idx = -1) { - max_cap = max(max_cap, cap); + max_cap = std::max(max_cap, cap); graph[from].emplace_back( (edge){to, cap, (int)graph[to].size(), false, idx}); graph[to].emplace_back( @@ -34,7 +42,7 @@ struct DinicCapacityScaling { bool build_augment_path(int s, int t, const flow_t& base) { min_cost.assign(graph.size(), -1); - queue que; + std::queue que; min_cost[s] = 0; que.push(s); while (!que.empty() && min_cost[t] == -1) { @@ -56,7 +64,8 @@ struct DinicCapacityScaling { for (int& i = iter[idx]; i < (int)graph[idx].size(); i++) { edge& e = graph[idx][i]; if (e.cap >= base && min_cost[idx] < min_cost[e.to]) { - flow_t d = find_augment_path(e.to, t, base, min(flow - sum, e.cap)); + flow_t d = + find_augment_path(e.to, t, base, std::min(flow - sum, e.cap)); if (d > 0) { e.cap -= d; graph[e.to][e.rev].cap += d; @@ -86,8 +95,8 @@ struct DinicCapacityScaling { for (auto& e : graph[i]) { if (e.isrev) continue; auto& rev_e = graph[e.to][e.rev]; - cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" - << e.cap + rev_e.cap << ")" << endl; + std::cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" + << e.cap + rev_e.cap << ")" << std::endl; } } } diff --git a/graph/flow/dinic.hpp b/graph/flow/dinic.hpp index cf658f411..0d403cdfe 100644 --- a/graph/flow/dinic.hpp +++ b/graph/flow/dinic.hpp @@ -1,3 +1,10 @@ +#pragma once + +#include +#include +#include +#include +#include /** * @brief Dinic(最大流) * @@ -14,10 +21,10 @@ struct Dinic { int idx; }; - vector > graph; - vector min_cost, iter; + std::vector > graph; + std::vector min_cost, iter; - explicit Dinic(int V) : INF(numeric_limits::max()), graph(V) {} + explicit Dinic(int V) : INF(std::numeric_limits::max()), graph(V) {} void add_edge(int from, int to, flow_t cap, int idx = -1) { graph[from].emplace_back( @@ -28,7 +35,7 @@ struct Dinic { bool build_augment_path(int s, int t) { min_cost.assign(graph.size(), -1); - queue que; + std::queue que; min_cost[s] = 0; que.push(s); while (!que.empty() && min_cost[t] == -1) { @@ -49,7 +56,7 @@ struct Dinic { for (int& i = iter[idx]; i < (int)graph[idx].size(); i++) { edge& e = graph[idx][i]; if (e.cap > 0 && min_cost[idx] < min_cost[e.to]) { - flow_t d = find_min_dist_augment_path(e.to, t, min(flow, e.cap)); + flow_t d = find_min_dist_augment_path(e.to, t, std::min(flow, e.cap)); if (d > 0) { e.cap -= d; graph[e.to][e.rev].cap += d; @@ -75,15 +82,15 @@ struct Dinic { for (auto& e : graph[i]) { if (e.isrev) continue; auto& rev_e = graph[e.to][e.rev]; - cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" - << e.cap + rev_e.cap << ")" << endl; + std::cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" + << e.cap + rev_e.cap << ")" << std::endl; } } } - vector min_cut(int s) { - vector used(graph.size()); - queue que; + std::vector min_cut(int s) { + std::vector used(graph.size()); + std::queue que; que.emplace(s); used[s] = true; while (not que.empty()) { diff --git a/graph/flow/ford-fulkerson.hpp b/graph/flow/ford-fulkerson.hpp index 10ac2e8a7..8bd9276e9 100644 --- a/graph/flow/ford-fulkerson.hpp +++ b/graph/flow/ford-fulkerson.hpp @@ -1,3 +1,9 @@ +#pragma once + +#include +#include +#include +#include /** * @brief Ford Fulkerson(最大流) * @@ -13,12 +19,12 @@ struct FordFulkerson { }; const flow_t INF; - vector > graph; - vector used; + std::vector > graph; + std::vector used; int timestamp; explicit FordFulkerson(int V) - : INF(numeric_limits::max()), + : INF(std::numeric_limits::max()), graph(V), used(V, -1), timestamp(0) {} @@ -35,7 +41,7 @@ struct FordFulkerson { used[idx] = timestamp; for (auto& e : graph[idx]) { if (e.cap > 0 && used[e.to] != timestamp) { - flow_t d = find_augment_path(e.to, t, min(flow, e.cap)); + flow_t d = find_augment_path(e.to, t, std::min(flow, e.cap)); if (d > 0) { e.cap -= d; graph[e.to][e.rev].cap += d; @@ -60,8 +66,8 @@ struct FordFulkerson { for (auto& e : graph[i]) { if (e.isrev) continue; auto& rev_e = graph[e.to][e.rev]; - cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" - << e.cap + rev_e.cap << ")" << endl; + std::cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" + << e.cap + rev_e.cap << ")" << std::endl; } } } diff --git a/graph/flow/gabow-edmonds.hpp b/graph/flow/gabow-edmonds.hpp index bbb61c0ba..caac195fc 100644 --- a/graph/flow/gabow-edmonds.hpp +++ b/graph/flow/gabow-edmonds.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include +#include // https://qiita.com/Kutimoti_T/items/5b579773e0a24d650bdf /** @@ -9,10 +14,10 @@ struct GabowEdmonds { int to, idx; }; - vector > g; - vector > edges; - vector mate, label, first; - queue que; + std::vector > g; + std::vector > edges; + std::vector mate, label, first; + std::queue que; GabowEdmonds(int n) : g(n + 1), mate(n + 1), label(n + 1, -1), first(n + 1) {} @@ -52,7 +57,7 @@ struct GabowEdmonds { label[r] = -num; label[s] = -num; while (true) { - if (s != 0) swap(r, s); + if (s != 0) std::swap(r, s); r = find(label[mate[r]]); if (label[r] == -num) { join = r; @@ -77,7 +82,7 @@ struct GabowEdmonds { } bool augment_check(int u) { - que = queue(); + que = std::queue(); first[u] = 0; label[u] = 0; que.push(u); @@ -102,12 +107,12 @@ struct GabowEdmonds { return false; } - vector > max_matching() { + std::vector > max_matching() { for (int i = 1; i < (int)g.size(); i++) { if (mate[i] != 0) continue; if (augment_check(i)) label.assign(g.size(), -1); } - vector > ret; + std::vector > ret; for (int i = 1; i < (int)g.size(); i++) { if (i < mate[i]) ret.emplace_back(i - 1, mate[i] - 1); } diff --git a/graph/flow/global-minimum-cut-of-dynamic-star-augmented-graph.hpp b/graph/flow/global-minimum-cut-of-dynamic-star-augmented-graph.hpp index 642c02788..bfa41cb7c 100644 --- a/graph/flow/global-minimum-cut-of-dynamic-star-augmented-graph.hpp +++ b/graph/flow/global-minimum-cut-of-dynamic-star-augmented-graph.hpp @@ -1,3 +1,9 @@ +#pragma once + +#include +#include +#include + #include "../../graph/tree/heavy-light-decomposition.hpp" #include "../../structure/class/range-add-range-min.hpp" #include "../../structure/segment-tree/lazy-segment-tree.hpp" @@ -8,7 +14,7 @@ struct GlobalMinimumCutofDynamicStarAugmentedGraph { private: int n{}; HeavyLightDecomposition hld; - vector cur; + std::vector cur; LazySegmentTree > seg; @@ -22,7 +28,7 @@ struct GlobalMinimumCutofDynamicStarAugmentedGraph { cur(n), seg(RangeAddRangeMin(), 2 * n - 1) { hld.build((int)hld.size() - 1); - vector vs(2 * n - 1); + std::vector vs(2 * n - 1); for (int i = 0; i < 2 * n - 1; i++) { for (auto& e : hld[i]) { vs[hld.in[e.to]] = e.cost; diff --git a/graph/flow/hungarian.hpp b/graph/flow/hungarian.hpp index f8f43583a..89d5ea6f2 100644 --- a/graph/flow/hungarian.hpp +++ b/graph/flow/hungarian.hpp @@ -1,3 +1,10 @@ +#pragma once + +#include +#include +#include +#include + #include "../../math/matrix/matrix.hpp" /** @@ -5,13 +12,13 @@ * */ template -pair > hungarian(Matrix& A) { - const T infty = numeric_limits::max(); +std::pair > hungarian(Matrix& A) { + const T infty = std::numeric_limits::max(); const int N = (int)A.height(); const int M = (int)A.width(); - vector P(M), way(M); - vector U(N, 0), V(M, 0), minV; - vector used; + std::vector P(M), way(M); + std::vector U(N, 0), V(M, 0), minV; + std::vector used; for (int i = 1; i < N; i++) { P[0] = i; diff --git a/graph/flow/maxflow-lower-bound.hpp b/graph/flow/maxflow-lower-bound.hpp index 3d39016a3..6991e5325 100644 --- a/graph/flow/maxflow-lower-bound.hpp +++ b/graph/flow/maxflow-lower-bound.hpp @@ -1,7 +1,13 @@ +#pragma once + +#include +#include +#include +#include template class F> struct MaxFlowLowerBound { F flow; - vector in, up; + std::vector in, up; int ts_edge, st_edge; int X, Y, V; flow_t sum; @@ -41,31 +47,31 @@ struct MaxFlowLowerBound { return ret >= sum; } - optional max_flow(int s, int t) { + std::optional max_flow(int s, int t) { if (can_flow(s, t)) { return flow.max_flow(s, t); } else { - return nullopt; + return std::nullopt; } } - optional min_flow(int s, int t) { + std::optional min_flow(int s, int t) { if (can_flow(s, t)) { auto ret = flow.INF - flow.graph[t][ts_edge].cap; flow.graph[t][ts_edge].cap = flow.graph[s][st_edge].cap = 0; return ret - flow.max_flow(t, s); } else { - return nullopt; + return std::nullopt; } } void output(int M) { - vector ans(M); + std::vector ans(M); for (int i = 0; i < flow.graph.size(); i++) { for (auto& e : flow.graph[i]) { if (!e.isrev && ~e.idx) ans[e.idx] = up[e.idx] - e.cap; } } - for (auto& p : ans) cout << p << endl; + for (auto& p : ans) std::cout << p << std::endl; } }; diff --git a/graph/flow/primal-dual.hpp b/graph/flow/primal-dual.hpp index 11ffd3c2b..4f91274fc 100644 --- a/graph/flow/primal-dual.hpp +++ b/graph/flow/primal-dual.hpp @@ -1,3 +1,12 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include /** * @brief Primal Dual(最小費用流) * @@ -12,12 +21,12 @@ struct PrimalDual { bool isrev; }; - vector > graph; - vector potential, min_cost; - vector prevv, preve; + std::vector > graph; + std::vector potential, min_cost; + std::vector prevv, preve; const cost_t INF; - PrimalDual(int V) : graph(V), INF(numeric_limits::max()) {} + PrimalDual(int V) : graph(V), INF(std::numeric_limits::max()) {} void add_edge(int from, int to, flow_t cap, cost_t cost) { graph[from].emplace_back( @@ -29,8 +38,8 @@ struct PrimalDual { cost_t min_cost_flow(int s, int t, flow_t f) { int V = (int)graph.size(); cost_t ret = 0; - using Pi = pair; - priority_queue, greater > que; + using Pi = std::pair; + std::priority_queue, std::greater > que; potential.assign(V, 0); preve.assign(V, -1); prevv.assign(V, -1); @@ -58,7 +67,7 @@ struct PrimalDual { for (int v = 0; v < V; v++) potential[v] += min_cost[v]; flow_t addflow = f; for (int v = t; v != s; v = prevv[v]) { - addflow = min(addflow, graph[prevv[v]][preve[v]].cap); + addflow = std::min(addflow, graph[prevv[v]][preve[v]].cap); } f -= addflow; ret += addflow * potential[t]; @@ -76,8 +85,8 @@ struct PrimalDual { for (auto& e : graph[i]) { if (e.isrev) continue; auto& rev_e = graph[e.to][e.rev]; - cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" - << rev_e.cap + e.cap << ")" << endl; + std::cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" + << rev_e.cap + e.cap << ")" << std::endl; } } } diff --git a/graph/flow/push-relabel.hpp b/graph/flow/push-relabel.hpp index 6904cff29..3a1a62326 100644 --- a/graph/flow/push-relabel.hpp +++ b/graph/flow/push-relabel.hpp @@ -1,7 +1,14 @@ +#pragma once + +#include +#include +#include +#include +#include class Stack { private: const int N, H; - vector node; + std::vector node; public: Stack(const int N, const int H) : N(N), H(H), node(N + H) { clear(); } @@ -16,7 +23,7 @@ class Stack { node[u] = node[N + h], node[N + h] = u; } - inline void clear() { iota(node.begin() + N, node.end(), N); } + inline void clear() { std::iota(node.begin() + N, node.end(), N); } }; class List { @@ -25,7 +32,7 @@ class List { int prev, next; }; const int N, H; - vector dat; + std::vector dat; List(const int N, const int H) : N(N), H(H), dat(N + H) { clear(); } @@ -60,11 +67,11 @@ struct PushRelabel { }; int V, height, relabels; - vector ex; - vector potential, cur_edge; + std::vector ex; + std::vector potential, cur_edge; List all_ver; Stack act_ver; - vector > graph; + std::vector > graph; PushRelabel(int V) : V(V), @@ -89,7 +96,7 @@ struct PushRelabel { for (int i = 0; i < V; i++) { if (potential[i] < V) { cur_edge[i] = 0; - height = max(height, potential[i]); + height = std::max(height, potential[i]); all_ver.insert(potential[i], i); if (ex[i] > 0 && i != t) act_ver.push(potential[i], i); } else { @@ -101,10 +108,10 @@ struct PushRelabel { void bfs(int t) { for (int i = 0; i < V; i++) { - potential[i] = max(potential[i], V); + potential[i] = std::max(potential[i], V); } potential[t] = 0; - queue que; + std::queue que; que.emplace(t); while (!que.empty()) { int p = que.front(); @@ -133,7 +140,7 @@ struct PushRelabel { } bool push(int u, int t, edge& e) { - flow_t f = min(e.cap, ex[u]); + flow_t f = std::min(e.cap, ex[u]); int v = e.to; e.cap -= f, ex[u] -= f; graph[v][e.rev].cap += f, ex[v] += f; @@ -182,7 +189,7 @@ struct PushRelabel { if ((potential[u] = cur) == V) return potential[u] = V + 1, prv; act_ver.push(cur, u); all_ver.insert(cur, u); - height = max(height, cur); + height = std::max(height, cur); } else { gap_relabel(u); return height = prv - 1; 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/mst/boruvka.hpp b/graph/mst/boruvka.hpp index 5f8799c1e..79f34e41f 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::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, std::make_pair(INF, -1)); update(v); bool con = false; for (int i = 0; i < (int)V; i++) { 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..32f838989 100644 --- a/graph/mst/manhattan-mst.hpp +++ b/graph/mst/manhattan-mst.hpp @@ -1,37 +1,47 @@ #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; } - swap(xs, ys); + std::swap(xs, ys); } for (int i = 0; i < n; i++) xs[i] *= -1; } diff --git a/graph/mst/prim-fibonacchi-heap.hpp b/graph/mst/prim-fibonacchi-heap.hpp index 46bfd1ece..d90e664c3 100644 --- a/graph/mst/prim-fibonacchi-heap.hpp +++ b/graph/mst/prim-fibonacchi-heap.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../../structure/heap/fibonacchi-heap.hpp" #include "../graph-template.hpp" @@ -19,16 +22,16 @@ MinimumSpanningTree prim_fibonacchi_heap(Graph& g) { using Node = typename Heap::Node; T total = 0; - vector*> dist(g.size()); - vector used(g.size()); + std::vector*> dist(g.size()); + std::vector used(g.size()); Heap heap; - vector keep(g.size(), nullptr); + std::vector keep(g.size(), nullptr); keep[0] = heap.push(0, 0); Edges es; while (!heap.empty()) { T cost; int idx; - tie(cost, idx) = heap.pop(); + std::tie(cost, idx) = heap.pop(); if (used[idx]) continue; used[idx] = true; total += cost; 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/bipartite-graph-edge-coloring.hpp b/graph/others/bipartite-graph-edge-coloring.hpp index a281dbde8..61e002e86 100644 --- a/graph/others/bipartite-graph-edge-coloring.hpp +++ b/graph/others/bipartite-graph-edge-coloring.hpp @@ -1,5 +1,13 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include + #include "../../structure/union-find/union-find.hpp" #include "../flow/bipartite-flow.hpp" #include "eulerian-trail.hpp" @@ -11,19 +19,19 @@ */ struct BipariteGraphEdgeColoring { private: - vector > ans; - vector A, B; + std::vector > ans; + std::vector A, B; int L, R; struct RegularGraph { int k{}, n{}; - vector A, B; + std::vector A, B; }; RegularGraph g; - static UnionFind contract(valarray& deg, int k) { - using pi = pair; - priority_queue, greater<> > que; + static UnionFind contract(std::valarray& deg, int k) { + using pi = std::pair; + std::priority_queue, std::greater<> > que; for (int i = 0; i < (int)deg.size(); i++) { que.emplace(deg[i], i); } @@ -42,35 +50,35 @@ struct BipariteGraphEdgeColoring { } RegularGraph build_k_regular_graph() { - valarray deg[2]; - deg[0] = valarray(L); - deg[1] = valarray(R); + std::valarray deg[2]; + deg[0] = std::valarray(L); + deg[1] = std::valarray(R); for (auto& p : A) deg[0][p]++; for (auto& p : B) deg[1][p]++; - int k = max(deg[0].max(), deg[1].max()); + int k = std::max(deg[0].max(), deg[1].max()); /* step 1 */ UnionFind uf[2]; uf[0] = contract(deg[0], k); uf[1] = contract(deg[1], k); - vector id[2]; + std::vector id[2]; int ptr[] = {0, 0}; - id[0] = vector(L); - id[1] = vector(R); + id[0] = std::vector(L); + id[1] = std::vector(R); for (int i = 0; i < L; i++) if (uf[0].find(i) == i) id[0][i] = ptr[0]++; for (int i = 0; i < R; i++) if (uf[1].find(i) == i) id[1][i] = ptr[1]++; /* step 2 */ - int N = max(ptr[0], ptr[1]); - deg[0] = valarray(N); - deg[1] = valarray(N); + int N = std::max(ptr[0], ptr[1]); + deg[0] = std::valarray(N); + deg[1] = std::valarray(N); /* step 3 */ - vector C, D; + std::vector C, D; C.reserve(N * k); D.reserve(N * k); for (int i = 0; i < (int)A.size(); i++) { @@ -95,7 +103,7 @@ struct BipariteGraphEdgeColoring { return {k, N, C, D}; } - void rec(const vector& ord, int k) { + void rec(const std::vector& ord, int k) { if (k == 0) { return; } else if (k == 1) { @@ -105,11 +113,11 @@ struct BipariteGraphEdgeColoring { EulerianTrail et(g.n + g.n); for (auto& p : ord) et.add_edge(g.A[p], g.B[p] + g.n); auto paths = et.enumerate_eulerian_trail(); - vector path; + std::vector path; for (auto& ps : paths) { for (auto& e : ps) path.emplace_back(ord[e]); } - vector beet[2]; + std::vector beet[2]; for (int i = 0; i < (int)path.size(); i++) { beet[i & 1].emplace_back(path[i]); } @@ -119,7 +127,7 @@ struct BipariteGraphEdgeColoring { BipartiteFlow flow(g.n, g.n); for (auto& i : ord) flow.add_edge(g.A[i], g.B[i]); flow.max_matching(); - vector beet; + std::vector beet; ans.emplace_back(); for (auto& i : ord) { if (flow.match_l[g.A[i]] == g.B[i]) { @@ -139,16 +147,16 @@ struct BipariteGraphEdgeColoring { void add_edge(int a, int b) { A.emplace_back(a); B.emplace_back(b); - L = max(L, a + 1); - R = max(R, b + 1); + L = std::max(L, a + 1); + R = std::max(R, b + 1); } - vector > build() { + std::vector > build() { g = build_k_regular_graph(); - vector ord(g.A.size()); - iota(ord.begin(), ord.end(), 0); + std::vector ord(g.A.size()); + std::iota(ord.begin(), ord.end(), 0); rec(ord, g.k); - vector > res; + std::vector > res; for (int i = 0; i < (int)ans.size(); i++) { res.emplace_back(); for (auto& j : ans[i]) 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/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..6e8c07efc 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,7 +80,7 @@ vector > enumerate_cliques(Matrix& g) { } } } - vector rem; + std::vector rem; for (int i = 0; i < N; i++) { if (!used[i]) rem.emplace_back(i); } 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..17e83b512 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]; 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..94d74b3b5 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,7 +46,7 @@ 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); } diff --git a/graph/others/minimum-steiner-tree.hpp b/graph/others/minimum-steiner-tree.hpp index c1c81d298..c8b368fed 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::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,6 @@ struct MinimumSteinerTree { private: const Graph& g; - const vector& terminal; - vector > pre; + const std::vector& terminal; + std::vector > pre; }; 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..4c399643b 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,17 +139,19 @@ void to_nice(vector& g, int root = 0) { if (g[idx].child.size() == 1) { int& ch = g[idx].child[0]; - 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(), - g[idx].bag.end(), back_inserter(malta)); + std::vector latte, malta; + std::set_difference(g[idx].bag.begin(), g[idx].bag.end(), + g[ch].bag.begin(), g[ch].bag.end(), + std::back_inserter(latte)); + std::set_difference(g[ch].bag.begin(), g[ch].bag.end(), + g[idx].bag.begin(), g[idx].bag.end(), + std::back_inserter(malta)); if (latte.size() + malta.size() > 1) { DecompNode r; r.child = {ch}; r.bag = g[idx].bag; if (!latte.empty()) { - r.bag.erase(find(r.bag.begin(), r.bag.end(), latte.back())); + r.bag.erase(std::find(r.bag.begin(), r.bag.end(), latte.back())); } else { r.bag.emplace_back(malta.back()); } diff --git a/graph/others/two-satisfiability.hpp b/graph/others/two-satisfiability.hpp index ddab76fa9..f55bbb6a5 100644 --- a/graph/others/two-satisfiability.hpp +++ b/graph/others/two-satisfiability.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../connected-components/strongly-connected-components.hpp" /** @@ -11,9 +14,9 @@ struct TwoSatisfiability : StronglyConnectedComponents { using StronglyConnectedComponents::g; using StronglyConnectedComponents::comp; using StronglyConnectedComponents::add_edge; - size_t sz; + std::size_t sz; - explicit TwoSatisfiability(size_t v) + explicit TwoSatisfiability(std::size_t v) : StronglyConnectedComponents(v + v), sz(v) {} void add_if(int u, int v) { @@ -47,10 +50,10 @@ struct TwoSatisfiability : StronglyConnectedComponents { return x + sz; } - vector solve() { + std::vector solve() { StronglyConnectedComponents::build(); - vector ret(sz); - for (size_t i = 0; i < sz; i++) { + std::vector ret(sz); + for (std::size_t i = 0; i < sz; i++) { if (comp[i] == comp[rev(i)]) return {}; ret[i] = comp[i] > comp[rev(i)]; } 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/complement-shotest-path.hpp b/graph/shortest-path/complement-shotest-path.hpp index 2f110fd7f..a93364fa2 100644 --- a/graph/shortest-path/complement-shotest-path.hpp +++ b/graph/shortest-path/complement-shotest-path.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" /** @@ -10,12 +15,13 @@ struct ComplementShortestPath : Graph { using Graph::Graph; using Graph::g; - vector > dists; + std::vector > dists; void build() { for (auto& es : g) { - sort(begin(es), end(es), - [&](const Edge& a, const Edge& b) { return a.to < b.to; }); + std::sort( + std::begin(es), std::end(es), + [&](const Edge& a, const Edge& b) { return a.to < b.to; }); } const int N = (int)g.size(); dists.resize(N); @@ -48,12 +54,12 @@ struct ComplementShortestPath : Graph { } } - vector complement_bfs(int s) { - vector dist(g.size(), -1); - queue que; + std::vector complement_bfs(int s) { + std::vector dist(g.size(), -1); + std::queue que; dist[s] = 0; que.emplace(s); - vector not_visited; + std::vector not_visited; for (int i = 0; i < g.size(); i++) { if (s != i) { not_visited.emplace_back(i); @@ -63,7 +69,7 @@ struct ComplementShortestPath : Graph { int idx = que.front(); que.pop(); int ptr = 0; - vector nxt_visited; + std::vector nxt_visited; for (auto& to : not_visited) { while (ptr < (int)g[idx].size() and g[idx][ptr].to < to) { ++ptr; @@ -75,7 +81,7 @@ struct ComplementShortestPath : Graph { que.emplace(to); } } - not_visited = move(nxt_visited); + not_visited = std::move(nxt_visited); } return dist; } diff --git a/graph/shortest-path/dijkstra-fibonacchi-heap.hpp b/graph/shortest-path/dijkstra-fibonacchi-heap.hpp index 69199b5e4..6eb650771 100644 --- a/graph/shortest-path/dijkstra-fibonacchi-heap.hpp +++ b/graph/shortest-path/dijkstra-fibonacchi-heap.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "../../structure/heap/fibonacchi-heap.hpp" #include "../graph-template.hpp" @@ -8,14 +13,14 @@ * */ template -vector dijkstra_fibonacchi_heap(Graph& g, int s) { - const auto INF = numeric_limits::max(); +std::vector dijkstra_fibonacchi_heap(Graph& g, int s) { + const auto INF = std::numeric_limits::max(); using Heap = FibonacchiHeap; using Node = typename Heap::Node; Heap heap; - vector keep(g.size(), nullptr); - vector dist; + std::vector keep(g.size(), nullptr); + std::vector dist; dist.assign(g.size(), INF); dist[s] = 0; keep[s] = heap.push(dist[s], s); @@ -23,7 +28,7 @@ vector dijkstra_fibonacchi_heap(Graph& g, int s) { while (!heap.empty()) { T cost; int idx; - tie(cost, idx) = heap.pop(); + std::tie(cost, idx) = heap.pop(); if (dist[idx] < cost) continue; for (auto& e : g[idx]) { auto next_cost = cost + e.cost; diff --git a/graph/shortest-path/dijkstra-radix-heap.hpp b/graph/shortest-path/dijkstra-radix-heap.hpp index 395ad1fd7..5b6a58cca 100644 --- a/graph/shortest-path/dijkstra-radix-heap.hpp +++ b/graph/shortest-path/dijkstra-radix-heap.hpp @@ -1,14 +1,20 @@ #pragma once +#include +#include +#include +#include + +#include "../../structure/heap/radix-heap.hpp" #include "../graph-template.hpp" /** * @brief Dijkstra-Radix-Heap(単一始点最短路) */ template -vector dijkstra_radix_heap(Graph& g, int s) { - const auto INF = numeric_limits::max(); - vector dist(g.size(), INF); +std::vector dijkstra_radix_heap(Graph& g, int s) { + const auto INF = std::numeric_limits::max(); + std::vector dist(g.size(), INF); RadixHeap heap; dist[s] = 0; @@ -16,7 +22,7 @@ vector dijkstra_radix_heap(Graph& g, int s) { while (!heap.empty()) { T cost; int idx; - tie(cost, idx) = heap.pop(); + std::tie(cost, idx) = heap.pop(); if (dist[idx] < cost) continue; for (auto& e : g.g[idx]) { auto next_cost = cost + e.cost; 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/k-shortest-path.hpp b/graph/shortest-path/k-shortest-path.hpp index 016abf71a..46ede1546 100644 --- a/graph/shortest-path/k-shortest-path.hpp +++ b/graph/shortest-path/k-shortest-path.hpp @@ -1,5 +1,17 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "../graph-template.hpp" /** @@ -8,14 +20,15 @@ * @see https://qiita.com/nariaki3551/items/821dc6ffdc552d3d5f22 */ template -vector > > k_shortest_path(const Graph& g, int s, int t, - int k) { +std::vector > > k_shortest_path(const Graph& g, + int s, int t, + int k) { assert(s != t); int N = (int)g.size(); int M = 0; for (int i = 0; i < N; i++) M += (int)g[i].size(); - vector latte(M), malta(M); - vector cost(M); + std::vector latte(M), malta(M); + std::vector cost(M); for (int i = 0; i < N; i++) { for (auto& e : g[i]) { latte[e.idx] = i; @@ -23,18 +36,18 @@ vector > > k_shortest_path(const Graph& g, int s, int t, cost[e.idx] = e.cost; } } - const auto INF = numeric_limits::max(); - vector dame(M, -1); + const auto INF = std::numeric_limits::max(); + std::vector dame(M, -1); int timestamp = 0; - auto shortest_path = [&](vector& dist, vector& from, vector& id, - int st) { - using Pi = pair; - priority_queue, greater<> > que; + auto shortest_path = [&](std::vector& dist, std::vector& from, + std::vector& id, int st) { + using Pi = std::pair; + std::priority_queue, std::greater<> > que; que.emplace(dist[st], st); 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; if (idx == t) return; @@ -49,25 +62,25 @@ vector > > k_shortest_path(const Graph& g, int s, int t, } } }; - auto restore = [](const vector& es, const vector& vs, int from, - int to) { - vector tap; + auto restore = [](const std::vector& es, const std::vector& vs, + int from, int to) { + std::vector tap; while (to != from) { tap.emplace_back(es[to]); to = vs[to]; } - reverse(begin(tap), end(tap)); + std::reverse(std::begin(tap), std::end(tap)); return tap; }; - vector dist(g.size(), INF); - vector from(g.size(), -1), id(g.size(), -1); + std::vector dist(g.size(), INF); + std::vector from(g.size(), -1), id(g.size(), -1); dist[s] = 0; shortest_path(dist, from, id, s); if (dist[t] == INF) return {}; - vector > > A; - set > > B; + std::vector > > A; + std::set > > B; A.emplace_back(dist[t], restore(id, from, s, t)); for (int i = 1; i < k; i++) { @@ -75,16 +88,16 @@ vector > > k_shortest_path(const Graph& g, int s, int t, from.assign(g.size(), -1); id.assign(g.size(), -1); dist[s] = 0; - vector candidate(A.size()); - iota(begin(candidate), end(candidate), 0); + std::vector candidate(A.size()); + std::iota(std::begin(candidate), std::end(candidate), 0); auto& last_path = A.back().second; int cur = s; for (int j = 0; j < last_path.size(); j++) { for (auto& k : candidate) { if (j < A[k].second.size()) dame[A[k].second[j]] = timestamp; } - vector dist2{dist}; - vector from2{from}, id2{id}; + std::vector dist2{dist}; + std::vector from2{from}, id2{id}; shortest_path(dist2, from2, id2, cur); ++timestamp; if (dist2[t] != INF) { @@ -98,7 +111,7 @@ vector > > k_shortest_path(const Graph& g, int s, int t, } if (ok) B.emplace(dist2[t], path); } - vector accept; + std::vector accept; for (auto& k : candidate) { if (j < A[k].second.size() && A[k].second[j] == last_path[j]) { accept.emplace_back(k); @@ -109,7 +122,7 @@ vector > > k_shortest_path(const Graph& g, int s, int t, from[malta[last_path[j]]] = latte[last_path[j]]; id[malta[last_path[j]]] = last_path[j]; cur = malta[last_path[j]]; - candidate = move(accept); + candidate = std::move(accept); } if (B.size()) { A.emplace_back(*B.begin()); diff --git a/graph/shortest-path/k-shortest-walk.hpp b/graph/shortest-path/k-shortest-walk.hpp index 5fd43c1d0..ee80a4508 100644 --- a/graph/shortest-path/k-shortest-walk.hpp +++ b/graph/shortest-path/k-shortest-walk.hpp @@ -1,5 +1,11 @@ #pragma once +#include +#include +#include +#include + +#include "../../structure/heap/persistent-leftist-heap.hpp" #include "../graph-template.hpp" /** @@ -8,7 +14,7 @@ * @see https://qiita.com/hotman78/items/42534a01c4bd05ed5e1e */ template -vector k_shortest_walk(const Graph& g, int s, int t, int k) { +std::vector k_shortest_walk(const Graph& g, int s, int t, int k) { int N = (int)g.size(); Graph rg(N); for (int i = 0; i < N; i++) { @@ -17,16 +23,16 @@ vector k_shortest_walk(const Graph& g, int s, int t, int k) { auto dist = dijkstra(rg, t); if (dist.from[s] == -1) return {}; auto& p = dist.dist; - vector > ch(N); + std::vector > ch(N); for (int i = 0; i < N; i++) { if (dist.from[i] >= 0) ch[dist.from[i]].emplace_back(i); } using PHeap = PersistentLeftistHeap; using Node = typename PHeap::Node; PHeap heap; - vector h(N, heap.make_root()); + std::vector h(N, heap.make_root()); { - queue que; + std::queue que; que.emplace(t); while (!que.empty()) { int idx = que.front(); @@ -46,17 +52,17 @@ vector k_shortest_walk(const Graph& g, int s, int t, int k) { for (auto& to : ch[idx]) que.emplace(to); } } - using pi = pair; + using pi = std::pair; auto comp = [](const pi& x, const pi& y) { return x.first > y.first; }; - priority_queue, decltype(comp)> que(comp); + std::priority_queue, decltype(comp)> que(comp); Node* root = heap.make_root(); root = heap.push(root, p[s], s); que.emplace(p[s], root); - vector ans; + std::vector ans; while (!que.empty()) { T cost; Node* cur; - tie(cost, cur) = que.top(); + std::tie(cost, cur) = que.top(); que.pop(); ans.emplace_back(cost); if ((int)ans.size() == k) break; diff --git a/graph/shortest-path/shortest-nonzero-path.hpp b/graph/shortest-path/shortest-nonzero-path.hpp index 7126861b4..2a886aad0 100644 --- a/graph/shortest-path/shortest-nonzero-path.hpp +++ b/graph/shortest-path/shortest-nonzero-path.hpp @@ -1,18 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include /** * @brief Shortest Nonzero Path(群ラベル制約付き単一始点最短路) */ template struct ShortestNonzeroPath { private: - constexpr static T INF = numeric_limits::max(); + constexpr static T INF = std::numeric_limits::max(); struct edge { int to; T cost; S label; }; - vector > g; + std::vector > g; F f; - vector uf; + std::vector uf; int find_uf(int k) { if (uf[k] == -1) return k; @@ -34,25 +43,25 @@ struct ShortestNonzeroPath { } struct SP { - vector dist; - vector depth, parent; - vector label; + std::vector dist; + std::vector depth, parent; + std::vector label; }; SP dijkstra(int s) { int n = (int)g.size(); - using pi = pair; - vector dist(n, INF); - vector depth(n, -1), parent(n, -1); - vector label(n, S()); - priority_queue, greater<> > que; + using pi = std::pair; + std::vector dist(n, INF); + std::vector depth(n, -1), parent(n, -1); + std::vector label(n, S()); + std::priority_queue, std::greater<> > que; dist[s] = T(0); depth[s] = 0; que.emplace(0, s); while (not que.empty()) { T cost; int u; - tie(cost, u) = que.top(); + std::tie(cost, u) = que.top(); que.pop(); if (dist[u] < cost) { continue; @@ -70,13 +79,13 @@ struct ShortestNonzeroPath { return {dist, depth, parent, label}; } - vector build(int s) { + std::vector build(int s) { int n = (int)g.size(); auto sp = dijkstra(s); uf.assign(n, -1); - using pi = tuple; - priority_queue, greater<> > que; + using pi = std::tuple; + std::priority_queue, std::greater<> > que; for (int u = 0; u < n; u++) { if (sp.dist[u] != INF) { for (int i = 0; i < (int)g[u].size(); i++) { @@ -87,12 +96,12 @@ struct ShortestNonzeroPath { } } } - vector dist(n, INF); - vector bs; + std::vector dist(n, INF); + std::vector bs; while (not que.empty()) { T cost; int u0, i; - tie(cost, u0, i) = que.top(); + std::tie(cost, u0, i) = que.top(); que.pop(); int v0 = g[u0][i].to; int u = find_uf(u0), v = find_uf(v0); diff --git a/graph/shortest-path/shortest-path-faster-algorithm.hpp b/graph/shortest-path/shortest-path-faster-algorithm.hpp index 60aebfd10..47a42d5c6 100644 --- a/graph/shortest-path/shortest-path-faster-algorithm.hpp +++ b/graph/shortest-path/shortest-path-faster-algorithm.hpp @@ -1,16 +1,21 @@ #pragma once +#include +#include +#include +#include + #include "../graph-template.hpp" /** * @brief Shortest-Path-Faster-Algorithm(単一始点最短路) */ template -vector shortest_path_faster_algorithm(const Graph& g, int s) { - const auto INF = numeric_limits::max(); - vector dist(g.size(), INF); - vector pending(g.size(), 0), times(g.size(), 0); - queue que; +std::vector shortest_path_faster_algorithm(const Graph& g, int s) { + const auto INF = std::numeric_limits::max(); + std::vector dist(g.size(), INF); + std::vector pending(g.size(), 0), times(g.size(), 0); + std::queue que; que.emplace(s); pending[s] = true; @@ -26,7 +31,7 @@ vector shortest_path_faster_algorithm(const Graph& g, int s) { if (next_cost >= dist[e.to]) continue; dist[e.to] = next_cost; if (!pending[e.to]) { - if (++times[e.to] >= (int)g.size()) return vector(); + if (++times[e.to] >= (int)g.size()) return std::vector(); pending[e.to] = true; que.emplace(e.to); } 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/graph/tree/centroid-decomposition.hpp b/graph/tree/centroid-decomposition.hpp index e6737e642..f4b9cdb56 100644 --- a/graph/tree/centroid-decomposition.hpp +++ b/graph/tree/centroid-decomposition.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "../graph-template.hpp" /** @@ -22,8 +24,8 @@ struct CentroidDecomposition : Graph { explicit CentroidDecomposition(const Graph& g) : Graph(g) {} private: - vector sub; - vector v; + std::vector sub; + std::vector v; inline int build_dfs(int idx, int par) { sub[idx] = 1; 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/disjoint-set-union-on-tree.hpp b/graph/tree/disjoint-set-union-on-tree.hpp index a7ea9632e..942f409d3 100644 --- a/graph/tree/disjoint-set-union-on-tree.hpp +++ b/graph/tree/disjoint-set-union-on-tree.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "../graph-template.hpp" /** @@ -7,19 +11,19 @@ */ template struct DisjointSetUnionOnTree : Graph { - using F = function; + using F = std::function; using Graph::g; - vector heavy, sz, in, out, ord; + std::vector heavy, sz, in, out, ord; const F expand, shrink, query; explicit DisjointSetUnionOnTree(int n, F expand, F shrink, F query) : Graph(n), - expand(move(expand)), - shrink(move(shrink)), - query(move(query)) {} + expand(std::move(expand)), + shrink(std::move(shrink)), + query(std::move(query)) {} private: - queue que; + std::queue que; int build_subtree(int idx) { in[idx] = ord.size(); diff --git a/graph/tree/doubling-lowest-common-ancestor.hpp b/graph/tree/doubling-lowest-common-ancestor.hpp index a3e4163ae..8b3cecf33 100644 --- a/graph/tree/doubling-lowest-common-ancestor.hpp +++ b/graph/tree/doubling-lowest-common-ancestor.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../graph-template.hpp" /** @@ -10,9 +13,9 @@ template struct DoublingLowestCommonAncestor : Graph { public: using Graph::g; - vector dep; - vector sum; - vector > table; + std::vector dep; + std::vector sum; + std::vector > table; const int LOG; explicit DoublingLowestCommonAncestor(int n) @@ -24,7 +27,7 @@ struct DoublingLowestCommonAncestor : Graph { void build(int root = 0) { dep.assign(g.size(), 0); sum.assign(g.size(), 0); - table.assign(LOG, vector(g.size(), -1)); + table.assign(LOG, std::vector(g.size(), -1)); dfs(root, -1, 0); for (int k = 0; k + 1 < LOG; k++) { for (int i = 0; i < (int)table[k].size(); i++) { @@ -37,7 +40,7 @@ struct DoublingLowestCommonAncestor : Graph { } int lca(int u, int v) { - if (dep[u] > dep[v]) swap(u, v); + if (dep[u] > dep[v]) std::swap(u, v); v = climb(v, dep[v] - dep[u]); if (u == v) return u; for (int i = LOG - 1; i >= 0; i--) { diff --git a/graph/tree/heavy-light-decomposition.hpp b/graph/tree/heavy-light-decomposition.hpp index 50aa386bc..e0566d223 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,17 +80,19 @@ 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)); + std::sort(std::begin(remark), std::end(remark), cmp); + remark.erase(std::unique(std::begin(remark), std::end(remark)), + std::end(remark)); int K = (int)remark.size(); for (int k = 1; k < K; k++) 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::sort(std::begin(remark), std::end(remark), cmp); + remark.erase(std::unique(std::begin(remark), std::end(remark)), + std::end(remark)); + 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 +108,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/offline-lca.hpp b/graph/tree/offline-lca.hpp index 57f813077..0e7537313 100644 --- a/graph/tree/offline-lca.hpp +++ b/graph/tree/offline-lca.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "../../structure/union-find/union-find.hpp" #include "../graph-template.hpp" @@ -5,15 +10,16 @@ * @brief Offline LCA(オフライン最小共通祖先) **/ template -vector offline_lca(const Graph& g, vector >& qs, - int root = 0) { +std::vector offline_lca(const Graph& g, + std::vector >& qs, + int root = 0) { int n = (int)g.size(); UnionFind uf(n); - vector st(n), mark(n), ptr(n), ans(qs.size(), -1); + std::vector st(n), mark(n), ptr(n), ans(qs.size(), -1); int top = 0; st[top] = root; for (auto& [l, r] : qs) mark[l]++, mark[r]++; - vector > > q(n); + std::vector > > q(n); for (int i = 0; i < n; i++) { q[i].reserve(mark[i]); mark[i] = -1; diff --git a/graph/tree/pmormq-lowest-common-ancestor.hpp b/graph/tree/pmormq-lowest-common-ancestor.hpp index bc702aadc..14a0a092d 100644 --- a/graph/tree/pmormq-lowest-common-ancestor.hpp +++ b/graph/tree/pmormq-lowest-common-ancestor.hpp @@ -1,5 +1,11 @@ #pragma once +#include +#include +#include +#include +#include + #include "../../structure/others/plus-minus-one-rmq.hpp" #include "../graph-template.hpp" @@ -12,25 +18,25 @@ struct PMORMQLowestCommonAncestor : Graph { public: using Graph::Graph; using Graph::g; - using F = function; + using F = std::function; void build(int root = 0) { ord.reserve(g.size() * 2 - 1); dep.reserve(g.size() * 2 - 1); in.resize(g.size()); dfs(root, -1, 0); - vector vs(g.size() * 2 - 1); - iota(begin(vs), end(vs), 0); + std::vector vs(g.size() * 2 - 1); + std::iota(std::begin(vs), std::end(vs), 0); st = PlusMinusOneRMQ(dep); } int lca(int x, int y) const { - if (in[x] > in[y]) swap(x, y); + if (in[x] > in[y]) std::swap(x, y); return ord[st.fold(in[x], in[y] + 1).second]; } private: - vector ord, dep, in; + std::vector ord, dep, in; PlusMinusOneRMQ st; void dfs(int idx, int par, int d) { 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/rmq-lowest-common-ancestor.hpp b/graph/tree/rmq-lowest-common-ancestor.hpp index 57a47ec6a..788aa748c 100644 --- a/graph/tree/rmq-lowest-common-ancestor.hpp +++ b/graph/tree/rmq-lowest-common-ancestor.hpp @@ -1,5 +1,11 @@ #pragma once +#include +#include +#include +#include +#include + #include "../../structure/others/sparse-table.hpp" #include "../graph-template.hpp" @@ -12,26 +18,26 @@ struct RMQLowestCommonAncestor : Graph { public: using Graph::Graph; using Graph::g; - using F = function; + using F = std::function; void build(int root = 0) { ord.reserve(g.size() * 2 - 1); dep.reserve(g.size() * 2 - 1); in.resize(g.size()); dfs(root, -1, 0); - vector vs(g.size() * 2 - 1); - iota(begin(vs), end(vs), 0); + std::vector vs(g.size() * 2 - 1); + std::iota(std::begin(vs), std::end(vs), 0); F f = [&](int a, int b) { return dep[a] < dep[b] ? a : b; }; st = get_sparse_table(vs, f); } int lca(int x, int y) const { - if (in[x] > in[y]) swap(x, y); + if (in[x] > in[y]) std::swap(x, y); return x == y ? x : ord[st.fold(in[x], in[y])]; } private: - vector ord, dep, in; + std::vector ord, dep, in; SparseTable st; void dfs(int idx, int par, int d) { diff --git a/graph/tree/static-top-tree-dp.hpp b/graph/tree/static-top-tree-dp.hpp index 89d277012..7c76aee98 100644 --- a/graph/tree/static-top-tree-dp.hpp +++ b/graph/tree/static-top-tree-dp.hpp @@ -1,3 +1,8 @@ +#pragma once + +#include +#include + #include "static-top-tree.hpp" template @@ -22,13 +27,13 @@ struct StaticTopTreeDP { modify(u); u = g[u].p; } - return get(dp[g.root]); + return std::get(dp[g.root]); } Path update_edge(int e) { return update_vertex(g.edge_to_vs[e]); } private: - vector > dp; + std::vector > dp; void modify(int k) { switch (g[k].op) { @@ -36,17 +41,18 @@ struct StaticTopTreeDP { dp[k] = info.vertex(k); return; case STT::Compress: - dp[k] = info.compress(get(dp[g[k].l]), get(dp[g[k].r]), - g[k].e_id); + dp[k] = info.compress(std::get(dp[g[k].l]), + std::get(dp[g[k].r]), g[k].e_id); return; case STT::Rake: - dp[k] = info.rake(get(dp[g[k].l]), get(dp[g[k].r])); + dp[k] = + info.rake(std::get(dp[g[k].l]), std::get(dp[g[k].r])); return; case STT::AddEdge: - dp[k] = info.add_edge(get(dp[g[k].l]), g[k].e_id); + dp[k] = info.add_edge(std::get(dp[g[k].l]), g[k].e_id); return; case STT::AddVertex: - dp[k] = info.add_vertex(get(dp[g[k].l]), k); + dp[k] = info.add_vertex(std::get(dp[g[k].l]), k); return; } } @@ -64,7 +70,7 @@ struct TreeDPInfo { struct Point {}; struct Path {}; - vector< int > A; + std::vector< int > A; TreeDPInfo(int n): A(n) {} diff --git a/graph/tree/static-top-tree.hpp b/graph/tree/static-top-tree.hpp index ed764bb46..c744b4ead 100644 --- a/graph/tree/static-top-tree.hpp +++ b/graph/tree/static-top-tree.hpp @@ -1,3 +1,10 @@ +#pragma once + +#include +#include +#include +#include +#include template struct StaticTopTree { enum OpType { Vertex, AddVertex, AddEdge, Rake, Compress }; @@ -12,9 +19,9 @@ struct StaticTopTree { Node(OpType op, int l, int r) : op{op}, l{l}, r{r}, p{-1}, e_id{-1} {} }; - vector vs; + std::vector vs; - vector edge_to_vs; + std::vector edge_to_vs; int root; @@ -34,12 +41,12 @@ struct StaticTopTree { const Node& operator[](int k) const { return vs[k]; } - size_t size() const { return vs.size(); } + std::size_t size() const { return vs.size(); } private: G& g; - using P = pair; + using P = std::pair; int dfs(int u) { int size = 1, heavy = 0; @@ -48,7 +55,7 @@ struct StaticTopTree { size += subtree_size; if (heavy < subtree_size) { heavy = subtree_size; - swap(v, g[u][0]); + std::swap(v, g[u][0]); } } return size; @@ -66,13 +73,13 @@ struct StaticTopTree { return k; } - P merge_forRake(const vector

& a) { + P merge_forRake(const std::vector

& a) { if (a.size() == 1) return a[0]; int size_sum = 0; for (auto& [_, size] : a) { size_sum += size; } - vector

b, c; + std::vector

b, c; for (auto& [it, size] : a) { (size_sum > size ? b : c).emplace_back(it, size); size_sum -= size * 2; @@ -82,13 +89,13 @@ struct StaticTopTree { return {make_node(Rake, l, r), l_size + r_size}; } - P merge_forCompress(const vector>& a) { + P merge_forCompress(const std::vector>& a) { if (a.size() == 1) return a[0].first; int size_sum = 0; for (auto& [it, _] : a) { size_sum += it.second; } - vector> b, c; + std::vector> b, c; for (auto& [it, _] : a) { (size_sum > it.second ? b : c).emplace_back(it, _); size_sum -= it.second * 2; @@ -110,7 +117,7 @@ struct StaticTopTree { } P rake(int u) { - vector

chs; + std::vector

chs; for (int j = 1; j < (int)g[u].size(); j++) { chs.emplace_back(add_edge(g[u][j].to, g[u][j].idx)); } @@ -127,8 +134,8 @@ struct StaticTopTree { } P compress(int u) { - vector> chs{{add_vertex(u), -1}}; - vector ids{-1}; + std::vector> chs{{add_vertex(u), -1}}; + std::vector ids{-1}; while (not g[u].empty()) { int e_idx = g[u][0].idx; u = g[u][0]; 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/graph/tree/tree-isomorphism.hpp b/graph/tree/tree-isomorphism.hpp index c9b5611b2..23ee94f3e 100644 --- a/graph/tree/tree-isomorphism.hpp +++ b/graph/tree/tree-isomorphism.hpp @@ -1,5 +1,13 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include + #include "../graph-template.hpp" #include "./centroid.hpp" @@ -11,12 +19,12 @@ bool tree_isomorphism(const Graph& a, const Graph& b) { if (a.size() != b.size()) return false; const int N = (int)a.size(); - using pvi = pair, vector >; + using pvi = std::pair, std::vector >; auto get_uku = [&](const Graph& t, int e) { - stack > st; + std::stack > st; st.emplace(e, -1); - vector dep(N, -1), par(N); + std::vector dep(N, -1), par(N); while (!st.empty()) { auto p = st.top(); if (dep[p.first] == -1) { @@ -28,27 +36,28 @@ bool tree_isomorphism(const Graph& a, const Graph& b) { st.pop(); } } - return make_pair(dep, par); + return std::make_pair(dep, par); }; auto solve = [&](const pvi& latte, const pvi& malta) { - int d = *max_element(begin(latte.first), end(latte.first)); - if (d != *max_element(begin(malta.first), end(malta.first))) return false; + int d = *std::max_element(std::begin(latte.first), std::end(latte.first)); + if (d != *std::max_element(std::begin(malta.first), std::end(malta.first))) + return false; - vector > latte_d(d + 1), malta_d(d + 1), latte_key(N), + std::vector > latte_d(d + 1), malta_d(d + 1), latte_key(N), malta_key(N); for (int i = 0; i < N; i++) latte_d[latte.first[i]].emplace_back(i); for (int i = 0; i < N; i++) malta_d[malta.first[i]].emplace_back(i); for (int i = d; i >= 0; i--) { - map, int> ord; + std::map, int> ord; for (auto& idx : latte_d[i]) { - sort(begin(latte_key[idx]), end(latte_key[idx])); + std::sort(std::begin(latte_key[idx]), std::end(latte_key[idx])); ord[latte_key[idx]]++; } for (auto& idx : malta_d[i]) { - sort(begin(malta_key[idx]), end(malta_key[idx])); + std::sort(std::begin(malta_key[idx]), std::end(malta_key[idx])); if (--ord[malta_key[idx]] < 0) return false; } if (i == 0) return ord.size() == 1; 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-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/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/enumeration.hpp b/math/combinatorics/enumeration.hpp index c90d9cb56..8e811904a 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) { + inline static void expand(std::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)); @@ -26,7 +32,7 @@ struct Enumeration { } public: - explicit Enumeration(size_t sz = 0) { expand(sz); } + explicit Enumeration(std::size_t sz = 0) { expand(sz); } static inline T fact(int k) { expand(k); @@ -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/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..cc19c1727 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); + for (std::int64_t i = p; i; i /= 2) (g *= a) %= 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/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/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/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/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/fps/bell.hpp b/math/fps/bell.hpp index a4c0f29a6..b5e12cf4d 100644 --- a/math/fps/bell.hpp +++ b/math/fps/bell.hpp @@ -1,3 +1,6 @@ +#pragma once + +#include /** * @brief Bell(ベル数) * diff --git a/math/fps/berlekamp-massey.hpp b/math/fps/berlekamp-massey.hpp index 70a527bb9..1553d604d 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; diff --git a/math/fps/bernoulli.hpp b/math/fps/bernoulli.hpp index 05de05629..956cdfe7c 100644 --- a/math/fps/bernoulli.hpp +++ b/math/fps/bernoulli.hpp @@ -1,3 +1,5 @@ +#pragma once + /** * @brief Bernoulli(ベルヌーイ数) */ 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