-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b301edb
commit a75b6d5
Showing
8 changed files
with
373 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#pragma once | ||
#include "IO.hpp" | ||
|
||
namespace FUN { | ||
bool isTriangle(ll x, ll y, ll z) { | ||
return (x + y > z and x + z > y and y + z > x); | ||
} | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#pragma once | ||
#include <bits/stdc++.h> | ||
using namespace std; | ||
|
||
using ll = long long; | ||
using ld = long double; | ||
|
||
template<typename T> inline T mini(T& x, T y) { return x = min(x, y); } | ||
template<typename T> inline T maxi(T& x, T y) { return x = max(x, y); } | ||
template <typename T> T rand(T x, T y) { return rand() % (y - x + 1) + x; } | ||
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#pragma once | ||
#include "flow_graph.hpp" | ||
|
||
template <typename T> | ||
class dinic { | ||
public: | ||
flow_graph<T>& g; | ||
|
||
vector<int> ptr; | ||
vector<int> d; | ||
vector<int> q; | ||
|
||
dinic(flow_graph<T>& _g) : g(_g) { | ||
ptr.resize(g.n); | ||
d.resize(g.n); | ||
q.resize(g.n); | ||
} | ||
|
||
bool expath() { | ||
fill(d.begin(), d.end(), -1); | ||
q[0] = g.fin; | ||
d[g.fin] = 0; | ||
int beg = 0, end = 1; | ||
while (beg < end) { | ||
int i = q[beg++]; | ||
for (int id : g.g[i]) { | ||
const auto& e = g.edges[id]; | ||
const auto& back = g.edges[id ^ 1]; | ||
if (back.c - back.f > g.eps && d[e.to] == -1) { | ||
d[e.to] = d[i] + 1; | ||
if (e.to == g.st) { | ||
return true; | ||
} | ||
q[end++] = e.to; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
T dfs(int v, T w) { | ||
if (v == g.fin) { | ||
return w; | ||
} | ||
int& j = ptr[v]; | ||
while (j >= 0) { | ||
int id = g.g[v][j]; | ||
const auto& e = g.edges[id]; | ||
if (e.c - e.f > g.eps && d[e.to] == d[v] - 1) { | ||
T t = dfs(e.to, min(e.c - e.f, w)); | ||
if (t > g.eps) { | ||
g.edges[id].f += t; | ||
g.edges[id ^ 1].f -= t; | ||
return t; | ||
} | ||
} | ||
j--; | ||
} | ||
return 0; | ||
} | ||
|
||
T max_flow() { | ||
while (expath()) { | ||
for (int i = 0; i < g.n; i++) { | ||
ptr[i] = (int) g.g[i].size() - 1; | ||
} | ||
T big_add = 0; | ||
while (true) { | ||
T add = dfs(g.st, numeric_limits<T>::max()); | ||
if (add <= g.eps) { | ||
break; | ||
} | ||
big_add += add; | ||
} | ||
if (big_add <= g.eps) { | ||
break; | ||
} | ||
g.flow += big_add; | ||
} | ||
return g.flow; | ||
} | ||
|
||
vector<bool> min_cut() { | ||
max_flow(); | ||
vector<bool> ret(g.n); | ||
for (int i = 0; i < g.n; i++) { | ||
ret[i] = (d[i] != -1); | ||
} | ||
return ret; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#pragma once | ||
#include "../IO.hpp" | ||
|
||
template <typename T> | ||
class flow_graph { | ||
public: | ||
static constexpr T eps = (T) 1e-9; | ||
|
||
struct edge { | ||
int from; | ||
int to; | ||
T c; | ||
T f; | ||
}; | ||
|
||
vector<vector<int>> g; | ||
vector<edge> edges; | ||
int n; | ||
int st; | ||
int fin; | ||
T flow; | ||
|
||
flow_graph(int _n, int _st, int _fin) : n(_n), st(_st), fin(_fin) { | ||
assert(0 <= st && st < n && 0 <= fin && fin < n && st != fin); | ||
g.resize(n); | ||
flow = 0; | ||
} | ||
|
||
void clear_flow() { | ||
for (const edge& e : edges) { | ||
e.f = 0; | ||
} | ||
flow = 0; | ||
} | ||
|
||
int add(int from, int to, T forward_cap, T backward_cap) { | ||
assert(0 <= from && from < n && 0 <= to && to < n); | ||
int id = (int) edges.size(); | ||
g[from].push_back(id); | ||
edges.push_back({from, to, forward_cap, 0}); | ||
g[to].push_back(id + 1); | ||
edges.push_back({to, from, backward_cap, 0}); | ||
return id; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#pragma once | ||
#include "../IO.hpp" | ||
|
||
using node = long long; | ||
// Neutral element is for calculations | ||
// TOOD: Check these elements | ||
static node NEUTERAL_ELEMENT; | ||
static node NO_OPS; | ||
|
||
struct segtreerange { | ||
int len{}; | ||
vector<node> ops; | ||
vector<node> values; | ||
|
||
node modify_op(const node& left, const node& right, long long v) { | ||
if (right == NO_OPS) return left; | ||
return right * v; | ||
} | ||
|
||
node cal_op(const node& left, const node& right) { | ||
return (left + right); | ||
} | ||
|
||
void apply(node& left, const node& right, long long v) { | ||
left = modify_op(left, right, v); | ||
} | ||
|
||
node single(node val) { | ||
return val; | ||
} | ||
|
||
void init(int n) { | ||
len = 1; | ||
while (len < n) len *= 2; | ||
ops.assign(2 * len, node{}); | ||
values.assign(2 * len, node{}); | ||
} | ||
|
||
explicit segtreerange(int n) { init(n); } | ||
|
||
explicit segtreerange(const vector<ll>& a) { | ||
init(a.size()); | ||
build(a, 0, 0, len); | ||
} | ||
|
||
void build(const vector<long long>& a, int x, int lx, int rx) { | ||
if (rx - lx == 1) { | ||
if (lx < (int) a.size()) { | ||
values[x] = single(a[lx]); | ||
} | ||
return; | ||
} | ||
int m = mid(lx, rx); | ||
build(a, 2 * x + 1, lx, m); | ||
build(a, 2 * x + 2, m, rx); | ||
values[x] = cal_op(values[2 * x + 1], values[2 * x + 2]); | ||
} | ||
|
||
void pull(int x, int lx, int rx) { | ||
if (rx - lx == 1)return; | ||
int m = mid(lx, rx); | ||
apply(values[2 * x + 1], ops[x], m - lx); | ||
apply(values[2 * x + 2], ops[x], rx - m); | ||
apply(ops[2 * x + 1], ops[x], 1); | ||
apply(ops[2 * x + 2], ops[x], 1); | ||
ops[x] = NO_OPS; | ||
} | ||
|
||
void update(int x, int lx, int rx, int l, int r, const node& val) { | ||
pull(x, lx, rx); | ||
if (lx >= r || l >= rx) return; | ||
if (lx >= l && rx <= r) { | ||
apply(ops[x], val, 1); | ||
apply(values[x], val, rx - lx); | ||
return; | ||
} | ||
int m = mid(lx, rx); | ||
update(2 * x + 1, lx, m, l, r, val); | ||
update(2 * x + 2, m, rx, l, r, val); | ||
values[x] = cal_op(values[2 * x + 1], values[2 * x + 2]); | ||
} | ||
|
||
// Update l....r-1 | ||
void update(int l, int r, node val) { | ||
update(0, 0, len, l, r, val); | ||
} | ||
|
||
node query(int x, int lx, int rx, int l, int r) { | ||
pull(x, lx, rx); | ||
if (lx >= r || l >= rx) return NEUTERAL_ELEMENT; | ||
if (lx >= l && rx <= r) { | ||
return values[x]; | ||
} | ||
int m = mid(lx, rx); | ||
auto m1 = query(2 * x + 1, lx, m, l, r); | ||
auto m2 = query(2 * x + 2, m, rx, l, r); | ||
return cal_op(m1, m2); | ||
} | ||
|
||
node query(int l, int r) { | ||
return query(0, 0, len, l, r); | ||
} | ||
int mid(int lx, int rx) { | ||
return (lx + rx) / 2; | ||
} | ||
}; |
Oops, something went wrong.