Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 54 additions & 28 deletions SELF_CONTAINED_HEADER_MIGRATION.md

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions dp/cumulative-sum-2d.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#pragma once

#include <vector>

template <class T>
struct CumulativeSum2D {
vector<vector<T> > data;
std::vector<std::vector<T> > data;

CumulativeSum2D(int W, int H) : data(W + 1, vector<T>(H + 1, 0)) {}
CumulativeSum2D(int W, int H) : data(W + 1, std::vector<T>(H + 1, 0)) {}

void add(int x, int y, T z) {
++x, ++y;
Expand Down
12 changes: 9 additions & 3 deletions dp/cumulative-sum.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <vector>

template <class T>
struct CumulativeSum {
vector<T> data;
std::vector<T> 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; }

Expand All @@ -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); }
Expand Down
15 changes: 10 additions & 5 deletions dp/divide-and-conquer-optimization.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
#pragma once

#include <functional>
#include <vector>

#include "monotone-minima.hpp"

template <typename T, typename Compare = less<T> >
vector<vector<T> > divide_and_conquer_optimization(
int H, int W, T INF, const function<T(int, int)>& f,
template <typename T, typename Compare = std::less<T> >
std::vector<std::vector<T> > divide_and_conquer_optimization(
int H, int W, T INF, const std::function<T(int, int)>& f,
const Compare& comp = Compare()) {
vector<vector<T> > dp(H + 1, vector<T>(W + 1, INF));
std::vector<std::vector<T> > dp(H + 1, std::vector<T>(W + 1, INF));
dp[0][0] = 0;
for (int i = 1; i <= H; i++) {
function<T(int, int)> get_cost = [&](int y, int x) {
std::function<T(int, int)> get_cost = [&](int y, int x) {
if (x >= y) return INF;
return dp[i - 1][x] + f(x, y);
};
Expand Down
16 changes: 11 additions & 5 deletions dp/edit-distance.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
int edit_distance(const string& S, const string& T) {
#pragma once

#include <algorithm>
#include <string>
#include <vector>

int edit_distance(const std::string& S, const std::string& T) {
const int N = (int)S.size(), M = (int)T.size();
vector<vector<int> > dp(N + 1, vector<int>(M + 1, N + M));
std::vector<std::vector<int> > dp(N + 1, std::vector<int>(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];
Expand Down
15 changes: 11 additions & 4 deletions dp/knapsack-01-2.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#pragma once

#include <algorithm>
#include <numeric>
#include <vector>

template <typename T>
T knapsack_01_2(const vector<T>& w, const vector<int>& v, const T& W) {
T knapsack_01_2(const std::vector<T>& w, const std::vector<int>& v,
const T& W) {
const int N = (int)w.size();
const int sum = accumulate(begin(v), end(v), 0);
vector<T> dp(sum + 1, W + 1);
const int sum = std::accumulate(v.begin(), v.end(), 0);
std::vector<T> 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;
Expand Down
14 changes: 10 additions & 4 deletions dp/knapsack-01.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
template <typename T, typename Compare = greater<T> >
vector<T> knapsack_01(const vector<int>& w, const vector<T>& v, const int& W,
const T& NG, const Compare& comp = Compare()) {
#pragma once

#include <functional>
#include <vector>

template <typename T, typename Compare = std::greater<T> >
std::vector<T> knapsack_01(const std::vector<int>& w, const std::vector<T>& v,
const int& W, const T& NG,
const Compare& comp = Compare()) {
const int N = (int)w.size();
vector<T> dp(W + 1, NG);
std::vector<T> dp(W + 1, NG);
dp[0] = T();
for (int i = 0; i < N; i++) {
for (int j = W; j >= w[i]; j--) {
Expand Down
33 changes: 20 additions & 13 deletions dp/knapsack-limitations-2.hpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
#pragma once

#include <algorithm>
#include <functional>
#include <numeric>
#include <vector>

#include "knapsack-limitations.hpp"

template <typename T>
T knapsack_limitations(const vector<T>& w, const vector<T>& m,
const vector<int>& v, const T& W) {
T knapsack_limitations(const std::vector<T>& w, const std::vector<T>& m,
const std::vector<int>& 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<int> ma(N);
vector<T> mb(N);
std::vector<int> ma(N);
std::vector<T> mb(N);
for (int i = 0; i < N; i++) {
ma[i] = min<T>(m[i], v_max - 1);
ma[i] = std::min<T>(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<int> 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<int> 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;
}
19 changes: 13 additions & 6 deletions dp/knapsack-limitations.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
template <typename T, typename Compare = greater<T> >
vector<T> knapsack_limitations(const vector<int>& w, const vector<int>& m,
const vector<T>& v, const int& W, const T& NG,
const Compare& comp = Compare()) {
#pragma once

#include <functional>
#include <vector>

template <typename T, typename Compare = std::greater<T> >
std::vector<T> knapsack_limitations(const std::vector<int>& w,
const std::vector<int>& m,
const std::vector<T>& v, const int& W,
const T& NG,
const Compare& comp = Compare()) {
const int N = (int)w.size();
vector<T> dp(W + 1, NG), deqv(W + 1);
std::vector<T> dp(W + 1, NG), deqv(W + 1);
dp[0] = T();
vector<int> deq(W + 1);
std::vector<int> deq(W + 1);
for (int i = 0; i < N; i++) {
if (w[i] == 0) {
for (int j = 0; j <= W; j++) {
Expand Down
14 changes: 10 additions & 4 deletions dp/knapsack.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
template <typename T, typename Compare = greater<T> >
vector<T> knapsack(const vector<int>& w, const vector<T>& v, const int& W,
const T& NG, const Compare& comp = Compare()) {
#pragma once

#include <functional>
#include <vector>

template <typename T, typename Compare = std::greater<T> >
std::vector<T> knapsack(const std::vector<int>& w, const std::vector<T>& v,
const int& W, const T& NG,
const Compare& comp = Compare()) {
const int N = (int)w.size();
vector<T> dp(W + 1, NG);
std::vector<T> dp(W + 1, NG);
dp[0] = T();
for (int i = 0; i < N; i++) {
for (int j = w[i]; j <= W; j++) {
Expand Down
18 changes: 13 additions & 5 deletions dp/largest-rectangle.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
#pragma once

#include <algorithm>
#include <cstdint>
#include <stack>
#include <vector>

template <typename T>
int64_t largest_rectangle(vector<T> height) {
stack<int> st;
std::int64_t largest_rectangle(std::vector<T> height) {
std::stack<int> st;
height.push_back(0);
vector<int> left(height.size());
int64_t ret = 0;
std::vector<int> 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();
Expand Down
19 changes: 13 additions & 6 deletions dp/longest-increasing-subsequence.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <vector>

template <typename T>
size_t longest_increasing_subsequence(const vector<T>& a, bool strict) {
vector<T> lis;
std::size_t longest_increasing_subsequence(const std::vector<T>& a,
bool strict) {
std::vector<T> lis;
for (auto& p : a) {
typename vector<T>::iterator it;
typename std::vector<T>::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;
Expand Down
22 changes: 14 additions & 8 deletions dp/monotone-minima.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
template <typename T, typename Compare = less<T> >
vector<pair<int, T> > monotone_minima(int H, int W,
const function<T(int, int)>& f,
const Compare& comp = Compare()) {
vector<pair<int, T> > dp(H);
function<void(int, int, int, int)> dfs = [&](int top, int bottom, int left,
int right) {
#pragma once

#include <functional>
#include <utility>
#include <vector>

template <typename T, typename Compare = std::less<T> >
std::vector<std::pair<int, T> > monotone_minima(
int H, int W, const std::function<T(int, int)>& f,
const Compare& comp = Compare()) {
std::vector<std::pair<int, T> > dp(H);
std::function<void(int, int, int, int)> dfs = [&](int top, int bottom,
int left, int right) {
if (top > bottom) return;
int line = (top + bottom) / 2;
T ma;
Expand All @@ -16,7 +22,7 @@ vector<pair<int, T> > 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);
};
Expand Down
42 changes: 24 additions & 18 deletions dp/online-offline-dp.hpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
#pragma once

#include <functional>
#include <vector>

#include "monotone-minima.hpp"

template <typename T, typename Compare = less<T> >
vector<T> online_offline_dp(int W, const function<T(int, int)>& f,
const Compare& comp = Compare()) {
vector<T> dp(W + 1);
vector<int> isset(W + 1);
template <typename T, typename Compare = std::less<T> >
std::vector<T> online_offline_dp(int W, const std::function<T(int, int)>& f,
const Compare& comp = Compare()) {
std::vector<T> dp(W + 1);
std::vector<int> isset(W + 1);
int y_base = -1, x_base = -1;
function<T(int, int)> get_cost =
std::function<T(int, int)> 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<void(int, int, int)> 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<void(int, int)> dfs = [&](int l, int r) {
std::function<void(int, int, int)> 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<void(int, int)> dfs = [&](int l, int r) {
if (l + 1 == r) {
x_base = l, y_base = l;
T cst = l ? get_cost(0, -1) : 0;
Expand Down
13 changes: 9 additions & 4 deletions geometry/angle.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#pragma once

#include <algorithm>
#include <cmath>

#include "point.hpp"

namespace geometry {
Expand All @@ -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
Loading
Loading