Skip to content

Commit

Permalink
Add old code
Browse files Browse the repository at this point in the history
  • Loading branch information
wmrmrx committed Mar 25, 2024
1 parent cb2cf32 commit e7769bf
Show file tree
Hide file tree
Showing 64 changed files with 3,749 additions and 0 deletions.
61 changes: 61 additions & 0 deletions old-code/data-structures/MO.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// MO algorithm

// Description:
// Answers queries offline with sqrt decomposition.
// Complexity:
// exec - O(n*sqrt(n)*O(remove / add))
const int magic = 230;

struct Query {
int l, r, idx;
Query () {}
Query (int _l, int _r, int _idx) : l(_l), r(_r), idx(_idx) {}
bool operator < (const Query &o) const {
return mp(l / magic, r) < mp(o.l / magic, o.r);
}
};

struct MO {
int sum;
MO(vector<ll> &v) : sum(0), v(v), cnt(N), C(N) {}

void exec(vector<Query> &queries, vector<ll> &answers) {
answers.resize(queries.size());
sort(queries.begin(), queries.end());

int cur_l = 0;
int cur_r = -1;

for (Query q : queries) {
while (cur_l > q.l) {
cur_l--;
add(cur_l);
}
while (cur_r < q.r) {
cur_r++;
add(cur_r);
}
while (cur_l < q.l) {
remove(cur_l);
cur_l++;
}
while (cur_r > q.r) {
remove(cur_r);
cur_r--;
}
answers[q.idx] = get_answer(cur_l, cur_r);
}
}

void add(int i) {
sum += v[i];
}

void remove(int i) {
sum -= v[i];
}

ll get_answer(int l, int r) {
return sum;
}
};
39 changes: 39 additions & 0 deletions old-code/data-structures/bit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Binary Indexed Tree

// !! zero indexed !!
// all operations are O(logN)

template<typename T> struct Bit {
vector<T> bit;
Bit(int n): bit(n) {}

void update(int id, T val) {
for(id+=1; id<=int(bit.size()); id+=id&-id)
bit[id-1] += val;
}

T query(int id) {
T sum = T();
for(id+=1; id>0; id-=id&-id)
sum += bit[id-1];
return sum;
}

// returns the first prefix for which sum of 0..=pos >= val
// returns bit.size() if such prefix doesnt exists
// it is necessary that v[i] >= 0 for all i for monotonicity
int lower_bound(T val) {
T sum = T();
int pos = 0;
int logn = 31 - __builtin_clz(bit.size());
for(int i=logn;i>=0;i--) {
int nxt = pos + (1<<i);
if(nxt <= int(bit.size())
&& sum + bit[nxt - 1] < val) {
sum += bit[nxt - 1];
pos = nxt;
}
}
return pos;
}
};
24 changes: 24 additions & 0 deletions old-code/data-structures/bit2D.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Binary Indexed Tree 2D

// 0-indexed
// update(x, y, val): m[row][col] += val
// query(x, y): returns sum m[0..=x][0..=y]
template <typename T> struct Bit2D {
int n, m;
vector<T> bit;
Bit2D(int _n, int _m): n(_n), m(_m), bit(n*m) {}

T query(int x, int y) {
T res = 0;
for(x+=1;x>0;x-=x&-x)
for(int z=y+1;z>0;z-=z&-z)
res += bit[(x-1)*m+z-1];
return res;
}

void update(int x, int y, T val) {
for(x+=1;x<=n;x+=x&-x)
for(int z=y+1;z<=m;z+=z&-z)
bit[(x-1)*m+z-1] += val;
}
};
140 changes: 140 additions & 0 deletions old-code/data-structures/implicit_lazy_treap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Implicit Lazy Treap

// All operations are O(log N)
// If changes need to be made in lazy propagation,
// See Node::push()
// To extend behavior of Treap, use inheritance
//
// Important functions:
// Treap::insert(int ind, T info)
// Treap::erase(int ind)
// Treap::reverse(int l, int r)
// Treap::operator[](int ind)

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

template <typename ND, typename T = typename ND::T>
struct Treap {
ND *root;
vector<ND> v;
// max: maximum number of NDs created
Treap(int max): root(0) {
v.reserve(max);
}
ND* new_node(T info) {
// assert(v.size() != v.capacity());
v.emplace_back(info);
return &v.back();
}
int getl(ND& nd) {
return nd.l ? nd.l->sz : 0;
}
void merge(ND* l, ND* r, ND*& res) {
if(!l || !r) {
res = l ? l : r;
return;
}
l->push(); r->push();
if(l->h > r->h) {
res = l;
merge(l->r, r, l->r);
} else {
res = r;
merge(l, r->l, r->l);
}
res->pull();
}
// left treap has size pos
void split(ND* x, ND*& l, ND*& r, int pos, int ra = 0) {
if(!x) {
l = r = 0;
return;
}
x->push();
int nra = ra + getl(*x) + 1;
if(pos < nra) {
split(x->l, l, r, pos, ra);
x->l = r;
r = x;
} else {
split(x->r, l, r, pos, nra);
x->r = l;
l = x;
}
x->pull();
}
// Merges all s and makes them root
template <int SZ>
void merge(array<ND*, SZ> s) {
root = 0;
for(ND* nd: s)
merge(root, nd, root);
}
// Splits root into SZ EXCLUSIVE intervals
// [0..s[0]), [s[0]..s[1]), [s[1]..s[2])... [s[SZ-1]..end)
// Example: split<3>({l, r}) gets the exclusive interval [l, r)
template <int SZ>
array<ND*, SZ> split(array<int, SZ-1> s) {
assert(s.back() <= (root ? root->sz : 0));
array<ND*, SZ> res;
split(root, res[0], res[1], s[0]);
for(int i=1;i<SZ-1;i++)
split(res[i], res[i], res[i+1], s[i]-s[i-1]);
root = 0;
return res;
}
void insert(int ind, T info) {
auto s = split<2>({ind});
merge<3>({s[0], new_node(info), s[1]});
}
void erase(int ind) {
auto s = split<3>({ind, ind+1});
merge<2>({s[0], s[2]});
}
T operator[](int ind) {
assert(0 <= ind && ind < root->sz);
ND* x = root;
x->push();
for(int ra = 0, nra = getl(*x); nra != ind; nra = ra + getl(*x)) {
if(nra < ind) ra = nra + 1, x = x->r;
else x = x->l;
x->push();
}
return x->info;
}
};

struct Node {
using T = int;
T info;
Node *l, *r;
int sz;
uint64_t h;
// more fields here - example: reverse interval
bool rev;
Node(T i): info(i), l(0), r(0), sz(1), h(rng()), rev(false) {}
void push() {
// example: reverse interval
if(rev) {
swap(l, r);
for(auto c: {l, r})
if(c) c->rev = !c->rev;
rev = false;
}
}
void pull() {
sz = 1;
for(auto c: {l, r})
if(c) sz += c->sz;
}
};

struct MyTreap : Treap<Node> {
MyTreap(int max): Treap<Node>(max) {}
// new methods here - example: reverse interval
void reverse(int l, int r) {
auto s = split<3>({l, r+1});
s[1]->rev = !s[1]->rev;
merge<3>(s):
}
};
58 changes: 58 additions & 0 deletions old-code/data-structures/linked_list.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Linked Linked
//
// Parameters:
// CAP: How many nodes can be created at most
// T: What type to be stored in a node in the linked list
//
// Functions:
// append(T info): puts node with info in the tail
// remove(Node* nd): removes node in O(1)
//
// Tested: https://codeforces.com/contest/1181/submission/246289459
namespace linked_list {
constexpr int CAP = 10'000'000;
using T = int;

struct Node {
T info;
Node *prv, *nxt;
};

Node arena[CAP];
int arena_cnt = 0;

struct LinkedList {
Node* new_node(T info) {
Node* ret = arena + (arena_cnt++);
ret->info = info;
ret->prv = ret->nxt = 0;
return ret;
}

Node *head, *tail;
LinkedList(): head(0), tail(0) {}
void append(T info) {
Node* nd = new_node(info);
if(!head)
head = tail = nd;
else {
tail->nxt = nd;
nd->prv = tail;
tail = nd;
}
}
void remove(Node* nd) {
if(nd == head && nd == tail)
head = tail = 0;
else if(nd == head)
head = nd->nxt, head->prv = 0;
else if(nd == tail)
tail = nd->prv, tail->nxt = 0;
else {
auto prv = nd->prv, nxt = nd->nxt;
prv->nxt = nxt;
nxt->prv = prv;
}
}
};
}
35 changes: 35 additions & 0 deletions old-code/data-structures/nce.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// NCE
// For each i, find nearest l < i < r such that
// op(l, i), op(r, i) = true if they exist
// l = -1, r = v.size() otherwise
//
// Example: nce(v, greater<T>()): for each i returns
// nce[i] = {
// biggest l < i such that v[l] > v[i]
// smallest r > i such that v[r] > v[i]
// }
//
// Complexity: O(N)

template <typename T, typename OP>
vector<pair<int, int>> nce(vector<T> v, OP op) {
int n = v.size();
vector<pair<int, int>> res(n);
vector<pair<T, int>> st;
for(int i=0;i<n;i++) {
while(!st.empty() && !op(st.back().first, v[i]))
st.pop_back();
if(st.empty()) res[i].first = -1;
else res[i].first = st.back().second;
st.emplace_back(v[i], i);
}
st.clear();
for(int i=n-1;i>=0;i--) {
while(!st.empty() && !op(st.back().first, v[i]))
st.pop_back();
if(st.empty()) res[i].second = n;
else res[i].second = st.back().second;
st.emplace_back(v[i], i);
}
return res;
}
7 changes: 7 additions & 0 deletions old-code/data-structures/ordered_set.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Ordered Set
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// iterator find_by_order(size_t index), size_t order_of_key(T key)
template <typename T>
using ordered_set=tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
28 changes: 28 additions & 0 deletions old-code/data-structures/rmq.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RMQ
// Description:
// Answers queries on a range.
// Complexity:
// build - O(N logN)
// query - O(1)

template <typename T> struct RMQ {
vector<vector<T>> dp;
T ops(T a, T b) { return min(a,b); }
RMQ() {}
RMQ(vector<T> v) {
int n = v.size();
int log = 32-__builtin_clz(n);
dp.assign(log, vector<T>(n));
copy(all(v), dp[0].begin());
for(int l=1;l<log;l++) for(int i=0;i<n;i++) {
auto &cur = dp[l], &ant = dp[l-1];
cur[i] = ops(ant[i], ant[min(i+(1<<(l-1)), n-1)]);
}
}
T query(int a, int b) {
if(a == b) return dp[0][a];
int p = 31-__builtin_clz(b-a);
auto &cur = dp[p];
return ops(cur[a], cur[b-(1<<p)+1]);
}
};
Loading

0 comments on commit e7769bf

Please sign in to comment.