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
5 changes: 0 additions & 5 deletions src/0-common/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<ll>>;
#define fr first
#define sc second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
16 changes: 8 additions & 8 deletions src/1-ds/fenwick_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
// usage: fenwick fw; fw.build(a); fw.add(p, x); fw.sum(l, r); fw.kth(k);
struct fenwick {
int n;
vl a, t;
vector<ll> a, t;
void init(int n_) {
// goal: allocate arrays for size n.
n = n_;
a.assign(n, 0);
t.assign(n, 0);
}
void build(const vl &v) {
void build(const vector<ll> &v) {
// goal: build fenwick in O(n) from initial array.
n = sz(v);
a = v;
Expand Down Expand Up @@ -60,7 +60,7 @@ struct fenwick {
// usage: fenw_range fw; fw.init(n); fw.add(l, r, x); ll v = fw.get(p);
struct fenw_range { // 1-indexed
int n;
vl t;
vector<ll> t;
void init(int n_) {
// goal: allocate internal tree (1-indexed).
n = n_;
Expand All @@ -85,19 +85,19 @@ struct fenw_range { // 1-indexed
// usage: fenw_2d fw; fw.build(a); fw.add(x, y, v); fw.sum(x1, y1, x2, y2);
struct fenw_2d { // 0-indexed
int n, m;
vvl a, t;
vector<vector<ll>> a, t;
void init(int n_, int m_) {
// goal: allocate arrays for n x m.
n = n_, m = m_;
a.assign(n, vl(m, 0));
t.assign(n, vl(m, 0));
a.assign(n, vector<ll>(m, 0));
t.assign(n, vector<ll>(m, 0));
}
void build(const vvl &v) {
void build(const vector<vector<ll>> &v) {
// goal: build 2D fenwick in O(n*m).
n = sz(v);
m = n ? sz(v[0]) : 0;
a = v;
t.assign(n, vl(m, 0));
t.assign(n, vector<ll>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
t[i][j] += a[i][j];
Expand Down
6 changes: 3 additions & 3 deletions src/1-ds/li_chao_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct li_chao {
void init(ll xl, ll xr) {
// goal: set x-range and clear tree.
t.clear();
t.pb({xl, xr, -1, -1, LINE_E});
t.push_back({xl, xr, -1, -1, LINE_E});
}
void add(lc_line nw, int v = 0) {
// goal: insert a new line into the segment.
Expand All @@ -40,14 +40,14 @@ struct li_chao {
t[v].ln = hi;
if (t[v].r == -1) {
t[v].r = sz(t);
t.pb({mid + 1, xr, -1, -1, LINE_E});
t.push_back({mid + 1, xr, -1, -1, LINE_E});
}
add(lo, t[v].r);
} else {
t[v].ln = lo;
if (t[v].l == -1) {
t[v].l = sz(t);
t.pb({xl, mid, -1, -1, LINE_E});
t.push_back({xl, mid, -1, -1, LINE_E});
}
add(hi, t[v].l);
}
Expand Down
12 changes: 6 additions & 6 deletions src/1-ds/merge_sort_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ constexpr int MAX_MST = 1 << 17;
// constraint: MAX_MST >= n; values fit in int; 0-indexed [l, r]; build once.
// usage: merge_seg st; st.build(a); st.query(l, r, k);
struct merge_seg {
vi t[MAX_MST << 1];
void build(const vi &a) {
vector<int> t[MAX_MST << 1];
void build(const vector<int> &a) {
// goal: build sorted lists for each node.
for (int i = 0; i < sz(a); i++)
t[i + MAX_MST].pb(a[i]);
t[i + MAX_MST].push_back(a[i]);
for (int i = MAX_MST - 1; i >= 1; i--) {
t[i].resize(sz(t[i << 1]) + sz(t[i << 1 | 1]));
merge(all(t[i << 1]), all(t[i << 1 | 1]), t[i].begin());
Expand All @@ -31,11 +31,11 @@ struct merge_seg {
// constraint: MAX_MST >= n; values fit in int; 0-indexed [l, r]; build once.
// usage: merge_seg_it st; st.build(a); st.query(l, r, k);
struct merge_seg_it {
vi t[MAX_MST << 1];
void build(const vi &a) {
vector<int> t[MAX_MST << 1];
void build(const vector<int> &a) {
// goal: build sorted lists for each node.
for (int i = 0; i < sz(a); i++)
t[i + MAX_MST].pb(a[i]);
t[i + MAX_MST].push_back(a[i]);
for (int i = MAX_MST - 1; i >= 1; i--) {
t[i].resize(sz(t[i << 1]) + sz(t[i << 1 | 1]));
merge(all(t[i << 1]), all(t[i << 1 | 1]), t[i].begin());
Expand Down
50 changes: 25 additions & 25 deletions src/1-ds/segment_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
// usage: seg_tree st; st.build(a); st.set(p, v); st.query(l, r);
struct seg_tree {
int flag;
vl t;
void build(const vl &a) {
vector<ll> t;
void build(const vector<ll> &a) {
// goal: build tree from 1-indexed array.
int n = sz(a) - 1;
flag = 1;
Expand Down Expand Up @@ -36,8 +36,8 @@ struct seg_tree {
// usage: seg_tree_it st; st.build(a); st.set(p, v); st.query(l, r);
struct seg_tree_it { // 0-indexed
int n;
vl t;
void build(const vl &a) {
vector<ll> t;
void build(const vector<ll> &a) {
// goal: build tree from 0-indexed array.
n = sz(a);
t.assign(2 * n, 0);
Expand Down Expand Up @@ -65,7 +65,7 @@ struct seg_tree_it { // 0-indexed
// usage: seg_tree_kth st; st.init(n); st.add(p, v); st.kth(k);
struct seg_tree_kth {
int flag;
vl t;
vector<ll> t;
void init(int n) {
// goal: allocate tree for size n.
flag = 1;
Expand All @@ -91,8 +91,8 @@ struct seg_tree_kth {
// usage: seg_tree_lz st; st.build(a); st.add(l, r, v); st.query(l, r);
struct seg_tree_lz {
int flag;
vl t, lz;
void build(const vl &a) {
vector<ll> t, lz;
void build(const vector<ll> &a) {
// goal: build tree and clear lazy tags.
int n = sz(a) - 1;
flag = 1;
Expand Down Expand Up @@ -149,19 +149,19 @@ struct seg_pst {
};
int n;
vector<node> t;
vi root;
vector<int> root;

void newnd() { t.pb({-1, -1, 0}); }
void build(int n_, const vl &a) {
void newnd() { t.push_back({-1, -1, 0}); }
void build(int n_, const vector<ll> &a) {
// goal: build initial version.
n = n_;
t.clear();
root.clear();
newnd();
root.pb(0);
root.push_back(0);
build(1, n, root[0], a);
}
void build(int l, int r, int v, const vl &a) {
void build(int l, int r, int v, const vector<ll> &a) {
// goal: build node v for range [l, r].
if (l == r) {
t[v].val = a[l];
Expand All @@ -179,7 +179,7 @@ struct seg_pst {
void set(int p, ll val) {
// goal: create new version with a[p] = val.
newnd();
root.pb(sz(t) - 1);
root.push_back(sz(t) - 1);
set(p, val, 1, n, root[sz(root) - 2], root.back());
}
void set(int p, ll val, int l, int r, int v1, int v2) {
Expand Down Expand Up @@ -246,13 +246,13 @@ struct seg_sparse {
if (p <= mid) {
if (t[v].l == -1) {
t[v].l = sz(t);
t.pb({0, -1, -1});
t.push_back({0, -1, -1});
}
add(p, x, t[v].l, nl, mid);
} else {
if (t[v].r == -1) {
t[v].r = sz(t);
t.pb({0, -1, -1});
t.push_back({0, -1, -1});
}
add(p, x, t[v].r, mid + 1, nr);
}
Expand All @@ -275,11 +275,11 @@ struct seg_sparse {
// usage: seg_2d st; st.build(a); st.set(x, y, v); st.query(x1, x2, y1, y2);
struct seg_2d { // 0-indexed
int n;
vvl t;
void build(const vvl &a) {
vector<vector<ll>> t;
void build(const vector<vector<ll>> &a) {
// goal: build 2D tree from initial grid.
n = sz(a);
t.assign(2 * n, vl(2 * n, 0));
t.assign(2 * n, vector<ll>(2 * n, 0));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
t[i + n][j + n] = a[i][j];
Expand Down Expand Up @@ -325,24 +325,24 @@ struct seg_2d { // 0-indexed
// usage: seg2d_comp st(n); st.mark_set(x, y); st.mark_qry(x1, x2, y1, y2); st.prep(); st.set(x, y, v); st.query(x1, x2, y1, y2);
struct seg2d_comp { // 0-indexed
int n;
vvl a;
vvi used;
vector<vector<ll>> a;
vector<vector<int>> used;
unordered_map<ll, ll> mp;
seg2d_comp(int n) : n(n), a(2 * n), used(2 * n) {}
void mark_set(int x, int y) {
// goal: record y-coordinates that will be updated.
for (x += n; x >= 1; x >>= 1) used[x].pb(y);
for (x += n; x >= 1; x >>= 1) used[x].push_back(y);
}
void mark_qry(int x1, int x2, int y1, int y2) {
// goal: record y-coordinates needed for queries.
for (x1 += n, x2 += n + 1; x1 < x2; x1 >>= 1, x2 >>= 1) {
if (x1 & 1) {
used[x1].pb(y1);
used[x1++].pb(y2);
used[x1].push_back(y1);
used[x1++].push_back(y2);
}
if (x2 & 1) {
used[--x2].pb(y1);
used[x2].pb(y2);
used[--x2].push_back(y1);
used[x2].push_back(y2);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/1-ds/union_find.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// constraint: 1-indexed [1, n].
// usage: dsu d; d.init(n); d.join(a, b); int r = d.find(x); int s = d.size(x);
struct dsu {
vi p;
vector<int> p;
void init(int n) { p.assign(n + 1, -1); } // goal: reset to n singletons.
int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); } // result: root of x.
int size(int x) { return -p[find(x)]; }
Expand Down
22 changes: 11 additions & 11 deletions src/2-graph/bcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
struct bcc_graph {
int n, tim;
vector<vector<pii>> adj;
vi dfn, low, ap, st;
vector<int> dfn, low, ap, st;
vector<pii> ed, ae;
vector<vector<pii>> bccs;

Expand All @@ -25,9 +25,9 @@ struct bcc_graph {
}
void add(int u, int v) {
int id = sz(ed);
ed.pb({u, v});
adj[u].pb({v, id});
adj[v].pb({u, id});
ed.push_back({u, v});
adj[u].push_back({v, id});
adj[v].push_back({u, id});
}
void dfs(int v, int pe) {
dfn[v] = low[v] = ++tim;
Expand All @@ -37,27 +37,27 @@ struct bcc_graph {
if (dfn[to] != -1) {
// edge: back edge to ancestor.
low[v] = min(low[v], dfn[to]);
if (dfn[to] < dfn[v]) st.pb(id);
if (dfn[to] < dfn[v]) st.push_back(id);
continue;
}
st.pb(id);
st.push_back(id);
ch++;
dfs(to, id);
low[v] = min(low[v], low[to]);
if (pe != -1 && low[to] >= dfn[v]) ap.pb(v);
if (low[to] > dfn[v]) ae.pb({min(v, to), max(v, to)});
if (pe != -1 && low[to] >= dfn[v]) ap.push_back(v);
if (low[to] > dfn[v]) ae.push_back({min(v, to), max(v, to)});
if (low[to] >= dfn[v]) {
vector<pii> comp;
while (1) {
int eid = st.back();
st.pop_back();
comp.pb(ed[eid]);
comp.push_back(ed[eid]);
if (eid == id) break;
}
bccs.pb(comp);
bccs.push_back(comp);
}
}
if (pe == -1 && ch > 1) ap.pb(v);
if (pe == -1 && ch > 1) ap.push_back(v);
}
void run() {
for (int v = 1; v <= n; v++)
Expand Down
14 changes: 7 additions & 7 deletions src/2-graph/euler_circuit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
// usage: euler_cir g; g.init(n); g.add(u,v); if (g.can()) auto path=g.run(1);
struct euler_cir {
int n;
vvi adj;
vi nxt, path;
vector<vector<int>> adj;
vector<int> nxt, path;

void init(int n_) {
// goal: allocate adjacency matrix and reset state.
n = n_;
adj.assign(n + 1, vi(n + 1));
adj.assign(n + 1, vector<int>(n + 1));
nxt.assign(n + 1, 1);
path.clear();
}
Expand All @@ -23,7 +23,7 @@ struct euler_cir {
}
bool can() {
// result: whether an Euler circuit exists.
vi deg(n + 1);
vector<int> deg(n + 1);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) deg[i] += adj[i][j];
for (int i = 1; i <= n; i++)
Expand All @@ -35,7 +35,7 @@ struct euler_cir {
break;
}
if (!s) return 1;
vi vis(n + 1);
vector<int> vis(n + 1);
queue<int> q;
q.push(s);
vis[s] = 1;
Expand All @@ -58,9 +58,9 @@ struct euler_cir {
dfs(i);
}
}
path.pb(v);
path.push_back(v);
}
vi run(int s = 1) {
vector<int> run(int s = 1) {
// result: Euler circuit starting from s (if exists).
for (int i = 1; i <= n; i++) nxt[i] = 1;
path.clear();
Expand Down
Loading