├── USACO ├── 2017 │ └── January │ │ ├── .DS_Store │ │ └── Gold │ │ ├── .DS_Store │ │ ├── P2_Hoof_Paper_Scissors.cpp │ │ └── P1_Balanced_Photo.cpp └── 2019 │ ├── .DS_Store │ ├── December │ ├── .DS_Store │ └── Gold │ │ ├── .DS_Store │ │ ├── P1_Milk_Pumping.cpp │ │ └── P2_Milk_Visits.cpp │ ├── February │ ├── .DS_Store │ └── Gold │ │ └── P1_CowLand.cpp │ └── January │ ├── .DS_Store │ └── Gold │ ├── .DS_Store │ └── P1_Time_Is_Mooney.cpp ├── README.md ├── Data Structures ├── FenwickTree.cpp ├── SparseTable.cpp ├── MonotonicCHT.cpp ├── Segment Trees │ ├── SegmentTree_Iterative.cpp │ ├── SegmentTree_Recursive.cpp │ └── SegmentTree_Lazy.cpp ├── XORTrie.cpp ├── LiChaoTree.cpp └── PersistentCHT.cpp ├── YouTube ├── Sparse_Table.cpp ├── Segment Tree - Majority Element │ └── Majority_Element.cpp └── Parallel Binary Search │ ├── Meteors_Normal.cpp │ └── Meteors_DnC.cpp ├── Strings └── Polynomial_Rolling_Hash.cpp └── Graphs ├── Dijkstra.cpp ├── 2-SAT.cpp ├── 2-Colouring.cpp └── LowestCommonAncestor_RMQ.cpp /USACO/2019/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2019/.DS_Store -------------------------------------------------------------------------------- /USACO/2017/January/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2017/January/.DS_Store -------------------------------------------------------------------------------- /USACO/2019/December/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2019/December/.DS_Store -------------------------------------------------------------------------------- /USACO/2019/February/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2019/February/.DS_Store -------------------------------------------------------------------------------- /USACO/2019/January/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2019/January/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # competitive-programming 2 | C++ implementations of some data structures and algorithms used in competitive programming. 3 | -------------------------------------------------------------------------------- /USACO/2017/January/Gold/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2017/January/Gold/.DS_Store -------------------------------------------------------------------------------- /USACO/2019/December/Gold/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2019/December/Gold/.DS_Store -------------------------------------------------------------------------------- /USACO/2019/January/Gold/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arujbansal/competitive-programming/HEAD/USACO/2019/January/Gold/.DS_Store -------------------------------------------------------------------------------- /Data Structures/FenwickTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct fenwick_tree { 3 | int n; 4 | vector tree; 5 | 6 | fenwick_tree(int _n = 0) { init(_n); } 7 | 8 | void init(int _n) { 9 | n = _n; 10 | tree.assign(n + 1, 0); 11 | } 12 | 13 | void build(const vector &a) { 14 | for (int i = 1; i <= n; i++) { 15 | int j = i + (i & -i); 16 | 17 | tree[i] += a[i - 1]; 18 | if (j <= n) tree[j] += tree[i]; 19 | } 20 | } 21 | 22 | void increment(int pos, T val) { 23 | for (int i = pos + 1; i <= n; i += i & -i) 24 | tree[i] += val; 25 | } 26 | 27 | T query(int pos) { 28 | T res = 0; 29 | 30 | for (int i = pos + 1; i > 0; i -= i & -i) 31 | res += tree[i]; 32 | 33 | return res; 34 | } 35 | 36 | T query(int l, int r) { return query(r) - query(l - 1); } 37 | }; -------------------------------------------------------------------------------- /Data Structures/SparseTable.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct SparseTable { 3 | int n, k; 4 | vector a; 5 | vector> st; 6 | 7 | void init(vector a) { 8 | this->a = a; 9 | n = (int) a.size(); 10 | k = lg(n); 11 | st.assign(n + 1, vector(k + 1)); 12 | build(); 13 | } 14 | 15 | int lg(int x) { return 31 - __builtin_clz(x); } 16 | 17 | int merge(int x, int y) { 18 | if (returnMax) return a[x] >= a[y] ? x : y; 19 | return a[x] < a[y] ? x : y; 20 | } 21 | 22 | void build() { 23 | for (int i = 0; i < n; i++) st[i][0] = i; 24 | 25 | for (int j = 1; j <= k; j++) 26 | for (int i = 0; i + (1 << j) - 1 < n; i++) 27 | st[i][j] = merge(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); 28 | } 29 | 30 | int query(int l, int r) { 31 | int j = lg(r - l + 1); 32 | 33 | int idx = merge(st[l][j], st[r - (1 << j) + 1][j]); 34 | return (returnIndex ? idx : a[idx]); 35 | } 36 | }; -------------------------------------------------------------------------------- /YouTube/Sparse_Table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | signed main() { 6 | ios_base::sync_with_stdio(false); 7 | cin.tie(nullptr); 8 | 9 | int N, Q; 10 | cin >> N >> Q; 11 | 12 | vector A(N); 13 | for (auto &x : A) 14 | cin >> x; 15 | 16 | vector lg(N + 1); // lg[i] = log2(i) 17 | lg[1] = 0; 18 | for (int i = 2; i <= N; i++) 19 | lg[i] = lg[i / 2] + 1; 20 | 21 | // sparse[i][j] : Minimum value in the interval [j, j + 2^i - 1] 22 | vector sparse(lg[N] + 1, vector(N)); 23 | 24 | for (int j = 0; j < N; j++) 25 | sparse[0][j] = A[j]; 26 | 27 | for (int i = 1; i <= lg[N]; i++) 28 | for (int j = 0; j + (1 << i) - 1 < N; j++) // (1 << x) = 2^x 29 | sparse[i][j] = min(sparse[i - 1][j], sparse[i - 1][j + (1 << (i - 1))]); 30 | 31 | while (Q--) { 32 | int l, r; 33 | cin >> l >> r; 34 | l--, r--; 35 | 36 | int i = lg[r - l + 1]; 37 | cout << min(sparse[i][l], sparse[i][r - (1 << i) + 1]) << "\n"; 38 | } 39 | } -------------------------------------------------------------------------------- /Data Structures/MonotonicCHT.cpp: -------------------------------------------------------------------------------- 1 | struct CHT { 2 | 3 | struct Line { 4 | int slope, yIntercept; 5 | 6 | Line(int slope, int yIntercept) : slope(slope), yIntercept(yIntercept) {} 7 | 8 | int val(int x) { 9 | return slope * x + yIntercept; 10 | } 11 | 12 | int intersect(Line y) { 13 | return (y.yIntercept - yIntercept + slope - y.slope - 1) / (slope - y.slope); 14 | } 15 | }; 16 | 17 | deque> dq; 18 | 19 | void insert(int slope, int yIntercept) { 20 | Line newLine(slope, yIntercept); 21 | 22 | while (!dq.empty() && dq.back().second >= dq.back().first.intersect(newLine)) 23 | dq.pop_back(); 24 | 25 | if (dq.empty()) { 26 | dq.emplace_back(newLine, 0); 27 | return; 28 | } 29 | 30 | dq.emplace_back(newLine, dq.back().first.intersect(newLine)); 31 | } 32 | 33 | int query(int x) { 34 | 35 | while (sz(dq) > 1) { 36 | if (dq[1].second <= x) dq.pop_front(); 37 | else break; 38 | } 39 | 40 | return dq[0].first.val(x); 41 | } 42 | 43 | int query2(int x) { 44 | auto qry = *lower_bound(dq.rbegin(), dq.rend(), 45 | make_pair(Line(0, 0), x), 46 | [&](const pair &a, const pair &b) { 47 | return a.second > b.second; 48 | }); 49 | 50 | return qry.first.val(x); 51 | } 52 | }; -------------------------------------------------------------------------------- /Strings/Polynomial_Rolling_Hash.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct polynomial_hash { 3 | int n; 4 | string s; 5 | T m, b; // prime mod, base 6 | vector hash, inverse; // hash[i] : hash value of s[0, i - 1] 7 | 8 | polynomial_hash() {} 9 | 10 | polynomial_hash(const string &_s, T _m, T _b) { 11 | init(_s, _m, _b); 12 | } 13 | 14 | void init(const string &_s, T _m, T _b) { 15 | s = _s; 16 | n = (int) (s.size()); 17 | m = _m; 18 | b = _b; 19 | hash.resize(n + 1); 20 | inverse.resize(n + 1); 21 | precompute(); 22 | } 23 | 24 | T binpow(T x, T y) { 25 | T res = 1; 26 | while (y > 0) { 27 | if (y % 2 != 0) res = (res * x) % m; 28 | x = (x * x) % m; 29 | y /= 2; 30 | } 31 | 32 | return res; 33 | } 34 | 35 | // Builds the hash and inverse array 36 | void precompute() { 37 | T power = b; 38 | hash[0] = 0; 39 | for (int i = 1; i <= n; i++) { 40 | hash[i] = (hash[i - 1] + (s[i - 1] - 'a' + 1) * power) % m; 41 | power = (power * b) % m; 42 | } 43 | 44 | inverse[n] = binpow(binpow(b, n), m - 2); 45 | for (int i = n - 1; i > 0; i--) 46 | inverse[i] = (inverse[i + 1] * b) % m; 47 | } 48 | 49 | // Returns the hash value of substring s[l, r] 50 | T get_hash(int l, int r) { 51 | l++, r++; 52 | if (l == 1) return hash[r]; 53 | return ((((hash[r] - hash[l - 1]) % m) + m) * inverse[l - 1]) % m; 54 | } 55 | }; -------------------------------------------------------------------------------- /USACO/2019/January/Gold/P1_Time_Is_Mooney.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * USACO 2020 January Contest, Gold 3 | * Problem 1. Time is Mooney 4 | * Problem Link: http://www.usaco.org/index.php?page=viewproblem2&cpid=993 5 | */ 6 | 7 | #include 8 | 9 | #define FAST_IO ios_base::sync_with_stdio(false), cin.tie(nullptr) 10 | #define setIO(i, o) freopen(i, "r", stdin), freopen(o, "w", stdout) 11 | #define trav(e, x) for (auto &(e) : (x)) 12 | #define pb(x) push_back(x) 13 | #define eb(x...) emplace_back(x) 14 | #define all(x) (x).begin(), (x).end() 15 | #define sz(x) (int) (x).size() 16 | #define lc(i) 2*i 17 | #define rc(i) 2*i+1 18 | #define int long long 19 | using namespace std; 20 | using ii = pair; 21 | using vi = vector; 22 | 23 | const int N = 1e3 + 1, MOD = 1e9 + 7, INF = 1e9 + 5; 24 | 25 | signed main() { 26 | FAST_IO; 27 | setIO("time.in", "time.out"); 28 | 29 | int n, m, c; 30 | cin >> n >> m >> c; 31 | int money[n]; 32 | for (int i = 0; i < n; i++) cin >> money[i]; 33 | vector edges; 34 | for (int i = 0; i < m; i++) { 35 | int u, v; 36 | cin >> u >> v; 37 | u--, v--; 38 | edges.eb(u, v); 39 | } 40 | int dp[n][N]; 41 | for (int i = 0; i < n; i++) for (int j = 0; j < N; j++) dp[i][j] = -1; 42 | dp[0][0] = 0; 43 | for (int j = 1; j < N; j++) { 44 | for (auto edge : edges) { 45 | int u = edge.first, v = edge.second; 46 | if (dp[u][j - 1] < 0) continue; 47 | dp[v][j] = max(dp[v][j], dp[u][j - 1] + money[v]); 48 | } 49 | } 50 | int ans = 0; 51 | for (int j = 0; j < N; j++) ans = max(ans, dp[0][j] - c * j * j); 52 | cout << ans; 53 | } 54 | -------------------------------------------------------------------------------- /USACO/2017/January/Gold/P2_Hoof_Paper_Scissors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * USACO 2017 January Contest, Gold 3 | * Problem 2. Hoof, Paper, Scissors 4 | */ 5 | 6 | #include 7 | 8 | #define FAST_IO ios_base::sync_with_stdio(false), cin.tie(nullptr) 9 | #define setIO(i, o) freopen(i, "r", stdin), freopen(o, "w", stdout) 10 | #define trav(e, x) for (auto &e : x) 11 | #define pb(x) push_back(x) 12 | #define eb(x...) emplace_back(x) 13 | #define all(x) x.begin(), x.end() 14 | #define sz(x) (int) (x).size() 15 | //#define int long long 16 | using namespace std; 17 | using vi = vector; 18 | using ii = pair; 19 | 20 | vector moves; 21 | 22 | bool beats(int x, int y) { 23 | if (x == 0 && y == 1) return true; 24 | if (x == 1 && y == 2) return true; 25 | if (x == 2 && y == 0) return true; 26 | return false; 27 | } 28 | 29 | // dp(i, j, k) : i - considering first i moves, j - gesture changes left, k - current gesture 30 | int dp[100005][25][3]; 31 | 32 | int f(int i, int j, int k) { 33 | if (i == 0) return (j < 0 ? 0 : beats(moves[i], k)); 34 | if (dp[i][j][k] > -1) return dp[i][j][k]; 35 | int ans = f(i - 1, j, k); 36 | for (int x = 0; x < 3; x++) { 37 | if (x == k) continue; 38 | if (j > 0) ans = max(ans, f(i - 1, j - 1, x)); 39 | } 40 | return dp[i][j][k] = beats(moves[i], k) + ans; 41 | } 42 | 43 | 44 | signed main() { 45 | FAST_IO; 46 | setIO("hps.in", "hps.out"); 47 | 48 | int n, k; 49 | cin >> n >> k; 50 | for (int i = 0; i < n; i++) { 51 | char x; 52 | cin >> x; 53 | int y; 54 | if (x == 'H') y = 0; 55 | else if (x == 'P') y = 1; 56 | else y = 2; 57 | moves.pb(y); 58 | } 59 | memset(dp, -1, sizeof dp); 60 | cout << max({f(n - 1, k, 0), f(n - 1, k, 1), f(n - 1, k, 2)}); 61 | } 62 | -------------------------------------------------------------------------------- /Data Structures/Segment Trees/SegmentTree_Iterative.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct segment_tree { 3 | int n; 4 | vector tree; 5 | T identity_element; 6 | function merge; 7 | 8 | segment_tree(int _n, T _identity_element, const function &_merge) { 9 | init(_n, _identity_element, _merge); 10 | } 11 | 12 | void init(int _n, T _identity_element, const function &_merge) { 13 | n = _n; 14 | identity_element = _identity_element; 15 | merge = _merge; 16 | tree.assign(2 * n, identity_element); 17 | } 18 | 19 | void build(const vector &a) { 20 | for (int i = 0; i < n; i++) 21 | tree[i + n] = a[i]; 22 | 23 | for (int i = n - 1; i > 0; i--) 24 | tree[i] = merge(tree[2 * i], tree[2 * i + 1]); 25 | } 26 | 27 | void identity_modify(int pos, T val) { 28 | pos += n; 29 | 30 | for (tree[pos] = merge(tree[pos], val); pos >>= 1; ) 31 | tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]); 32 | } 33 | 34 | void increment(int pos, T val) { 35 | pos += n; 36 | 37 | for (tree[pos] += val; pos >>= 1; ) 38 | tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]); 39 | } 40 | 41 | void set(int pos, T val) { 42 | pos += n; 43 | 44 | for (tree[pos] = val; pos >>= 1; ) 45 | tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]); 46 | } 47 | 48 | T query(int l, int r) { 49 | T res = identity_element; 50 | 51 | for (l += n, r += n; l <= r; l >>= 1, r >>= 1) { 52 | if (l & 1) res = merge(res, tree[l++]); 53 | if (!(r & 1)) res = merge(res, tree[r--]); 54 | } 55 | 56 | return res; 57 | } 58 | 59 | T query(int pos) { return query(pos, pos); } 60 | }; -------------------------------------------------------------------------------- /Data Structures/XORTrie.cpp: -------------------------------------------------------------------------------- 1 | const int bits = 29; 2 | 3 | struct XORTrie { 4 | 5 | struct Node { 6 | array child; 7 | int cnt; 8 | 9 | Node() { 10 | cnt = 0; 11 | child[0] = -1; 12 | child[1] = -1; 13 | } 14 | }; 15 | 16 | vector t; 17 | 18 | XORTrie() { 19 | t.emplace_back(); 20 | t.emplace_back(); 21 | }; 22 | 23 | void create_children(int i) { 24 | if (t[i].child[0] > -1) return; 25 | 26 | for (int idx = 0; idx < 2; idx++) { 27 | t[i].child[idx] = sz(t); 28 | t.emplace_back(); 29 | } 30 | } 31 | 32 | void add(int x) { 33 | int idx = 1; 34 | 35 | for (int bit = bits; bit >= 0; bit--) { 36 | create_children(idx); 37 | 38 | int visit = (x & (1ll << bit)) > 0; 39 | 40 | idx = t[idx].child[visit]; 41 | t[idx].cnt++; 42 | } 43 | } 44 | 45 | void remove(int x) { 46 | int idx = 1; 47 | 48 | for (int bit = bits; bit >= 0; bit--) { 49 | create_children(idx); 50 | 51 | int visit = (x & (1ll << bit)) > 0; 52 | 53 | if (t[t[idx].child[visit]].cnt > 0) 54 | idx = t[idx].child[visit]; 55 | else break; 56 | 57 | t[idx].cnt--; 58 | } 59 | } 60 | 61 | int query(int x) { 62 | int idx = 1; 63 | 64 | int res = 0; 65 | 66 | for (int bit = bits; bit >= 0; bit--) { 67 | int visit = ((x & (1ll << bit)) > 0) ^ 1; 68 | 69 | create_children(idx); 70 | 71 | if (t[t[idx].child[visit]].cnt > 0) { 72 | res |= (1ll << bit); 73 | idx = t[idx].child[visit]; 74 | } else idx = t[idx].child[visit ^ 1]; 75 | } 76 | 77 | return res; 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /Graphs/Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Dijkstra { 3 | const T INF = numeric_limits::max(); 4 | 5 | struct state { 6 | int u; 7 | T dist; 8 | 9 | state() {} 10 | 11 | state(int _u, T _dist) : u(_u), dist(_dist) {} 12 | 13 | bool operator<(const state &other) const { 14 | return dist > other.dist; 15 | } 16 | }; 17 | 18 | int n; 19 | vector>> graph; 20 | vector dist; 21 | vector parent; 22 | 23 | Dijkstra(int _n = 0) { 24 | init(_n); 25 | } 26 | 27 | void init(int _n) { 28 | n = _n; 29 | graph.resize(n); 30 | } 31 | 32 | void add_directional_edge(int u, int v, T weight) { 33 | graph[u].emplace_back(v, weight); 34 | } 35 | 36 | void add_bidirectional_edge(int u, int v, T weight) { 37 | add_directional_edge(u, v, weight); 38 | add_directional_edge(v, u, weight); 39 | } 40 | 41 | void run(const vector &source) { 42 | priority_queue pq; 43 | dist.assign(n, INF); 44 | parent.assign(n, -1); 45 | 46 | for (const auto &u : source) { 47 | dist[u] = 0; 48 | parent[u] = u; 49 | 50 | pq.emplace(u, 0); 51 | } 52 | 53 | while (!pq.empty()) { 54 | auto [u, cur_dist] = pq.top(); 55 | pq.pop(); 56 | 57 | if (dist[u] != cur_dist) continue; 58 | 59 | for (const auto &[v, weight] : graph[u]) { 60 | T new_dist = cur_dist + weight; 61 | 62 | if (new_dist < dist[v]) { 63 | dist[v] = new_dist; 64 | parent[v] = u; 65 | pq.emplace(v, new_dist); 66 | } 67 | } 68 | } 69 | } 70 | 71 | bool reachable(int u) { 72 | return dist[u] < INF; 73 | } 74 | }; -------------------------------------------------------------------------------- /Graphs/2-SAT.cpp: -------------------------------------------------------------------------------- 1 | struct two_sat { 2 | int n; 3 | vector> g, gr; 4 | vector comp, topological_order, answer; 5 | vector vis; 6 | 7 | two_sat() {} 8 | 9 | two_sat(int _n) { init(_n); } 10 | 11 | void init(int _n) { 12 | n = _n; 13 | g.assign(2 * n, vector()); 14 | gr.assign(2 * n, vector()); 15 | comp.resize(2 * n); 16 | vis.resize(2 * n); 17 | answer.resize(2 * n); 18 | } 19 | 20 | void add_edge(int u, int v) { 21 | g[u].push_back(v); 22 | gr[v].push_back(u); 23 | } 24 | 25 | // At least one of them is true 26 | void add_clause_or(int i, bool f, int j, bool g) { 27 | add_edge(i + (f ? n : 0), j + (g ? 0 : n)); 28 | add_edge(j + (g ? n : 0), i + (f ? 0 : n)); 29 | } 30 | 31 | // Only one of them is true 32 | void add_clause_xor(int i, bool f, int j, bool g) { 33 | add_clause_or(i, f, j, g); 34 | add_clause_or(i, !f, j, !g); 35 | } 36 | 37 | // Both of them have the same value 38 | void add_clause_and(int i, bool f, int j, bool g) { 39 | add_clause_xor(i, !f, j, g); 40 | } 41 | 42 | void dfs(int u) { 43 | vis[u] = true; 44 | 45 | for (const auto &v : g[u]) 46 | if (!vis[v]) dfs(v); 47 | 48 | topological_order.push_back(u); 49 | } 50 | 51 | void scc(int u, int id) { 52 | vis[u] = true; 53 | comp[u] = id; 54 | 55 | for (const auto &v : gr[u]) 56 | if (!vis[v]) scc(v, id); 57 | } 58 | 59 | bool satisfiable() { 60 | fill(vis.begin(), vis.end(), false); 61 | 62 | for (int i = 0; i < 2 * n; i++) 63 | if (!vis[i]) dfs(i); 64 | 65 | fill(vis.begin(), vis.end(), false); 66 | reverse(topological_order.begin(), topological_order.end()); 67 | 68 | int id = 0; 69 | for (const auto &v : topological_order) 70 | if (!vis[v]) scc(v, id++); 71 | 72 | for (int i = 0; i < n; i++) { 73 | if (comp[i] == comp[i + n]) return false; 74 | answer[i] = (comp[i] > comp[i + n] ? 1 : 0); 75 | } 76 | 77 | return true; 78 | } 79 | }; -------------------------------------------------------------------------------- /YouTube/Segment Tree - Majority Element/Majority_Element.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int MXN = 3e5 + 5; 8 | int N, K; 9 | int A[MXN]; 10 | pair tree[4 * MXN]; 11 | 12 | pair merge(const pair &x, const pair &y) { 13 | if (x.first == y.first) 14 | return make_pair(x.first, x.second + y.second); 15 | 16 | if (x.second > y.second) 17 | return make_pair(x.first, x.second - y.second); 18 | 19 | return make_pair(y.first, y.second - x.second); 20 | } 21 | 22 | void build(int i, int l, int r) { 23 | if (l == r) { 24 | tree[i] = make_pair(A[l], 1); 25 | return; 26 | } 27 | 28 | int mid = (l + r) / 2; 29 | 30 | build(2 * i, l, mid); 31 | build(2 * i + 1, mid + 1, r); 32 | 33 | tree[i] = merge(tree[2 * i], tree[2 * i + 1]); 34 | } 35 | 36 | pair query(int i, int l, int r, int ql, int qr) { 37 | if (l > qr || r < ql) return make_pair(-1, 0); 38 | if (l >= ql && r <= qr) return tree[i]; 39 | 40 | int mid = (l + r) / 2; 41 | return merge(query(2 * i, l, mid, ql, qr), query(2 * i + 1, mid + 1, r, ql, qr)); 42 | } 43 | 44 | signed main() { 45 | cin >> N >> K; 46 | 47 | vector pos[MXN]; 48 | for (int i = 0; i < MXN; i++) 49 | pos[i].push_back(-1); 50 | 51 | for (int i = 0; i < N; i++) { 52 | cin >> A[i]; 53 | pos[A[i]].push_back(i); 54 | } 55 | 56 | build(1, 0, N - 1); 57 | 58 | int Q; 59 | cin >> Q; 60 | 61 | while (Q--) { 62 | int l, r; 63 | cin >> l >> r; 64 | l--, r--; 65 | 66 | int candidate = query(1, 0, N - 1, l, r).first; 67 | 68 | if (candidate < 0) { 69 | cout << "no\n"; 70 | continue; 71 | } 72 | 73 | auto lb = lower_bound(pos[candidate].begin(), pos[candidate].end(), l); 74 | lb--; 75 | 76 | auto ub = upper_bound(pos[candidate].begin(), pos[candidate].end(), r); 77 | ub--; 78 | 79 | int freq = (ub - pos[candidate].begin()) - (lb - pos[candidate].begin()); 80 | 81 | if (freq * 2 > r - l + 1) cout << "yes " << candidate << "\n"; 82 | else cout << "no\n"; 83 | } 84 | } -------------------------------------------------------------------------------- /Graphs/2-Colouring.cpp: -------------------------------------------------------------------------------- 1 | struct UFDS { 2 | int n; 3 | vector info; 4 | 5 | UFDS() {} 6 | 7 | UFDS(int _n) { init(_n); } 8 | 9 | void init(int _n) { 10 | n = _n; 11 | info.assign(n, -1); 12 | } 13 | 14 | int get(int x) { 15 | if (info[x] < 0) return x; 16 | return info[x] = get(info[x]); 17 | } 18 | 19 | bool unite(int x, int y) { 20 | x = get(x), y = get(y); 21 | if (x == y) return false; 22 | 23 | if (info[x] > info[y]) 24 | swap(x, y); 25 | 26 | info[x] += info[y]; 27 | info[y] = x; 28 | 29 | return true; 30 | } 31 | 32 | bool connected(int x, int y) { return get(x) == get(y); } 33 | }; 34 | 35 | struct two_colouring { 36 | int n; 37 | UFDS ufds; 38 | vector answer, in_answer; 39 | 40 | two_colouring(int _n) { init(_n); } 41 | 42 | void init(int _n) { 43 | n = _n; 44 | ufds.init(2 * n); 45 | } 46 | 47 | void add_clause_equal(int x, int y) { 48 | ufds.unite(x, y); 49 | ufds.unite(x + n, y + n); 50 | } 51 | 52 | void add_clause_opposite(int x, int y) { 53 | ufds.unite(x, y + n); 54 | ufds.unite(x + n, y); 55 | } 56 | 57 | bool satisfiable() { 58 | for (int i = 0; i < n; i++) 59 | if (ufds.connected(i, i + n)) return false; 60 | 61 | return true; 62 | } 63 | 64 | // Construct an answer where we minimise the number of "which" values in each component 65 | // which is either 1 or 0 66 | void construct_answer(int which) { 67 | answer.resize(n); 68 | in_answer.assign(2 * n, 0); 69 | vector cnt(2 * n, 0); 70 | 71 | for (int i = 0; i < 2 * n; i++) 72 | cnt[ufds.get(i)] += (i > n) ^ which; 73 | 74 | for (int i = 0; i < n; i++) { 75 | int cur = ufds.get(i), complement = ufds.get(i + n); 76 | 77 | if (in_answer[cur] || in_answer[complement]) 78 | continue; 79 | 80 | if (cnt[cur] < cnt[complement]) 81 | in_answer[cur] = true; 82 | else 83 | in_answer[complement] = true; 84 | } 85 | 86 | for (int i = 0; i < n; i++) 87 | answer[i] = (in_answer[ufds.get(i)] ? 1 : 0); 88 | } 89 | }; -------------------------------------------------------------------------------- /USACO/2019/December/Gold/P1_Milk_Pumping.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * USACO 2019 December Contest, Gold 3 | * Problem 1. Milk Pumping 4 | * Problem Link: http://www.usaco.org/index.php?page=viewproblem2&cpid=969 5 | */ 6 | 7 | #include 8 | 9 | #define FAST_IO ios_base::sync_with_stdio(false), cin.tie(nullptr) 10 | #define setIO(i, o) freopen(i, "r", stdin), freopen(o, "w", stdout) 11 | #define trav(e, x) for (auto &e : x) 12 | #define pb(x) push_back(x) 13 | #define eb(x...) emplace_back(x) 14 | #define all(x) (x).begin(), (x).end() 15 | #define sz(x) (int) (x).size() 16 | #define lc(i) 2*i 17 | #define rc(i) 2*i+1 18 | //#define int long long 19 | using namespace std; 20 | using ii = pair; 21 | using vi = vector; 22 | 23 | const int MAXN = 1e3 + 5, INF = 1e9 + 5, MOD = 1e9 + 7; 24 | int n, m; 25 | 26 | struct edge { 27 | int u, v, c, f; 28 | }; 29 | 30 | vector edges; 31 | vector adj[MAXN]; 32 | vi dist; 33 | 34 | int dijkstra(int flow) { 35 | for (int i = 0; i < n; i++) adj[i].clear(); 36 | dist.assign(n, INF); 37 | for (auto e: edges) { 38 | if (e.f >= flow) { 39 | adj[e.u].eb(e.v, e.c); 40 | adj[e.v].eb(e.u, e.c); 41 | } 42 | } 43 | dist[0] = 0; 44 | priority_queue, greater> pq; 45 | pq.emplace(0, 0); 46 | while (!pq.empty()) { 47 | ii cur = pq.top(); 48 | pq.pop(); 49 | int u = cur.second, curC = cur.first; 50 | if (dist[u] != curC) continue; 51 | trav(e, adj[u]) { 52 | int v = e.first; 53 | int cost = e.second; 54 | if (dist[u] + cost < dist[v]) { 55 | dist[v] = dist[u] + cost; 56 | pq.emplace(dist[v], v); 57 | } 58 | } 59 | } 60 | return (dist[n - 1] < INF ? dist[n - 1] : -1); 61 | } 62 | 63 | signed main() { 64 | FAST_IO; 65 | setIO("pump.in", "pump.out"); 66 | 67 | cin >> n >> m; 68 | for (int i = 0; i < m; i++) { 69 | int u, v, c, f; 70 | cin >> u >> v >> c >> f; 71 | u--, v--; 72 | edges.eb(edge{u, v, c, f}); 73 | } 74 | double res = 0; 75 | for (int i = 1; i <= 1000; i++) { 76 | int shortest = dijkstra(i); 77 | if (shortest > -1) res = max(res, (double) i / shortest); 78 | } 79 | cout << (int) (res * 1000000); 80 | } 81 | -------------------------------------------------------------------------------- /USACO/2017/January/Gold/P1_Balanced_Photo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * USACO 2017 January Contest, Gold 3 | * Problem 1. Balanced Photo 4 | * Problem Link: http://www.usaco.org/index.php?page=viewproblem2&cpid=693 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define FAST_IO ios_base::sync_with_stdio(false), cin.tie(nullptr) 11 | #define setIO(i, o) freopen(i, "r", stdin), freopen(o, "w", stdout) 12 | #define trav(e, x) for (auto &e : x) 13 | #define pb(x) push_back(x) 14 | #define eb(x...) emplace_back(x) 15 | #define all(x) x.begin(), x.end() 16 | #define sz(x) (int) (x).size() 17 | #define lc(i) 2*i 18 | #define rc(i) 2*i+1 19 | //#define int long long 20 | using namespace std; 21 | using namespace __gnu_pbds; 22 | using vi = vector; 23 | using ii = pair; 24 | using ht = gp_hash_table; 25 | 26 | struct SegmentTree { 27 | vector t; 28 | int n; 29 | 30 | void init(int x) { 31 | n = x; 32 | t.assign(2 * n, 0); 33 | } 34 | 35 | static int merge(int x, int y) { return x + y; } 36 | 37 | void modify(int p) { 38 | for (t[p += n]++; p /= 2;) t[p] = merge(t[lc(p)], t[rc(p)]); 39 | } 40 | 41 | int query(int l, int r) { 42 | int res = 0; 43 | for (l += n, r += n; l < r; l /= 2, r /= 2) { 44 | if (l & 1) res = merge(res, t[l++]); 45 | if (r & 1) res = merge(res, t[--r]); 46 | } 47 | return res; 48 | } 49 | 50 | }; 51 | 52 | signed main() { 53 | FAST_IO; 54 | setIO("bphoto.in", "bphoto.out"); 55 | 56 | int n; 57 | cin >> n; 58 | vi a(n), a2(n); 59 | for (int i = 0; i < n; i++) { 60 | cin >> a[i]; 61 | a2[i] = a[i]; 62 | } 63 | sort(all(a2)); 64 | map val; 65 | int last = 1; 66 | trav(x, a2) if (val[x] == 0) val[x] = last++; 67 | trav(x, a) x = val[x] - 1; 68 | 69 | SegmentTree invL, invR; 70 | invL.init(n), invR.init(n); 71 | int cnt[n][2]; 72 | for (int i = 0, j = n - 1; i < n; i++, j--) { 73 | cnt[i][0] = invL.query(a[i], n); 74 | invL.modify(a[i]); 75 | cnt[j][1] = invR.query(a[j], n); 76 | invR.modify(a[j]); 77 | } 78 | 79 | int ans = 0; 80 | for (int i = 0; i < n; i++) { 81 | int l = cnt[i][0], r = cnt[i][1]; 82 | if (max(l, r) > 2 * min(l, r)) ans++; 83 | } 84 | cout << ans; 85 | } 86 | -------------------------------------------------------------------------------- /Graphs/LowestCommonAncestor_RMQ.cpp: -------------------------------------------------------------------------------- 1 | struct LCA { 2 | int n, k; 3 | vector> adj, sparse_table; 4 | vector euler, first_occurrence; 5 | int timer; 6 | bool lca_built; 7 | 8 | LCA(int _n = 0) { 9 | lca_built = false; 10 | 11 | if (_n > 0) 12 | init(_n); 13 | } 14 | 15 | void init(int _n) { 16 | lca_built = false; 17 | 18 | n = _n; 19 | 20 | adj.resize(n); 21 | for (int i = 0; i < n; i++) 22 | adj[i].clear(); 23 | 24 | euler.clear(); 25 | first_occurrence.resize(n); 26 | timer = 0; 27 | } 28 | 29 | void add_edge(int u, int v) { 30 | assert(n > 0); 31 | 32 | adj[u].push_back(v); 33 | adj[v].push_back(u); 34 | } 35 | 36 | void run(int root = 0) { 37 | assert(n > 0); 38 | 39 | dfs(root, -1); 40 | build(); 41 | 42 | lca_built = true; 43 | } 44 | 45 | void dfs(int u = 0, int p = -1) { 46 | first_occurrence[u] = timer++; 47 | euler.push_back(u); 48 | 49 | for (const auto &v : adj[u]) { 50 | if (v == p) continue; 51 | 52 | dfs(v, u); 53 | euler.push_back(u); 54 | timer++; 55 | } 56 | } 57 | 58 | void build() { 59 | k = 31 - __builtin_clz(timer) + 1; 60 | 61 | sparse_table.resize(k); 62 | 63 | for (int i = 0; i < k; i++) 64 | sparse_table[i].resize(timer - (1 << i) + 1); 65 | 66 | for (int j = 0; j < timer; j++) 67 | sparse_table[0][j] = euler[j]; 68 | 69 | for (int i = 1; i < k; i++) { 70 | for (int j = 0; j + (1 << i) - 1 < timer; j++) { 71 | int x = sparse_table[i - 1][j]; 72 | int y = sparse_table[i - 1][j + (1 << (i - 1))]; 73 | 74 | sparse_table[i][j] = (first_occurrence[x] < first_occurrence[y] ? x : y); 75 | } 76 | } 77 | } 78 | 79 | int query(int u, int v) { 80 | assert(lca_built == true); 81 | 82 | int l = first_occurrence[u], r = first_occurrence[v]; 83 | if (l > r) 84 | swap(l, r); 85 | 86 | int i = 31 - __builtin_clz(r - l + 1); 87 | 88 | int x = sparse_table[i][l], y = sparse_table[i][r - (1 << i) + 1]; 89 | return first_occurrence[x] < first_occurrence[y] ? x : y; 90 | } 91 | }; -------------------------------------------------------------------------------- /Data Structures/Segment Trees/SegmentTree_Recursive.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct segment_tree { 3 | int n; 4 | vector a, tree; 5 | T identity; 6 | function merge; 7 | 8 | segment_tree() {} 9 | 10 | segment_tree(int _n, T _identity, const function &_merge) { 11 | init(_n, _identity, _merge); 12 | } 13 | 14 | void init(int _n, T _identity, const function &_merge) { 15 | n = _n; 16 | identity = _identity; 17 | merge = _merge; 18 | 19 | tree.assign(4 * n, identity); 20 | } 21 | 22 | void build(int i, int l, int r) { 23 | if (l == r) { 24 | tree[i] = a[l]; 25 | return; 26 | } 27 | 28 | int mid = (l + r) / 2; 29 | build(2 * i, l, mid); 30 | build(2 * i + 1, mid + 1, r); 31 | 32 | tree[i] = merge(tree[2 * i], tree[2 * i + 1]); 33 | } 34 | 35 | void identity_modify(int i, int l, int r, int pos, T val) { 36 | if (l == r) { 37 | tree[i] = merge(tree[i], val); 38 | return; 39 | } 40 | 41 | int mid = (l + r) / 2; 42 | if (pos <= mid) identity_modify(2 * i, l, mid, pos, val); 43 | else identity_modify(2 * i + 1, mid + 1, r, pos, val); 44 | 45 | tree[i] = merge(tree[2 * i], tree[2 * i + 1]); 46 | } 47 | 48 | void increment(int i, int l, int r, int pos, T val) { 49 | if (l == r) { 50 | tree[i] += val; 51 | return; 52 | } 53 | 54 | int mid = (l + r) / 2; 55 | if (pos <= mid) increment(2 * i, l, mid, pos, val); 56 | else increment(2 * i + 1, mid + 1, r, pos, val); 57 | 58 | tree[i] = merge(tree[2 * i], tree[2 * i + 1]); 59 | } 60 | 61 | T query(int i, int l, int r, int ql, int qr) { 62 | if (l > qr || r < ql) return identity; 63 | if (l >= ql && r <= qr) return tree[i]; 64 | 65 | int mid = (l + r) / 2; 66 | T resL = query(2 * i, l, mid, ql, qr); 67 | T resR = query(2 * i + 1, mid + 1, r, ql, qr); 68 | 69 | return merge(resL, resR); 70 | } 71 | 72 | void build(const vector &_a) { 73 | a = _a; 74 | build(1, 0, n - 1); 75 | } 76 | 77 | void identity_modify(int pos, T val) { identity_modify(1, 0, n - 1, pos, val); } 78 | 79 | void increment(int pos, T val) { increment(1, 0, n - 1, pos, val); } 80 | 81 | T query(int pos) { return query(1, 0, n - 1, pos, pos); } 82 | 83 | T query(int l, int r) { return query(1, 0, n - 1, l, r); } 84 | }; -------------------------------------------------------------------------------- /USACO/2019/December/Gold/P2_Milk_Visits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * USACO 2019 December Contest, Gold 3 | * Problem 2. Milk Visits 4 | * Problem Link: http://www.usaco.org/index.php?page=viewproblem2&cpid=970 5 | */ 6 | 7 | #include 8 | 9 | #define FAST_IO ios_base::sync_with_stdio(false), cin.tie(nullptr) 10 | #define setIO(i, o) freopen(i, "r", stdin), freopen(o, "w", stdout) 11 | #define trav(e, x) for (auto &(e) : (x)) 12 | #define pb(x) push_back(x) 13 | #define eb(x...) emplace_back(x) 14 | #define all(x) (x).begin(), (x).end() 15 | #define sz(x) (int) (x).size() 16 | #define lc(i) 2*i 17 | #define rc(i) 2*i+1 18 | //#define int long long 19 | using namespace std; 20 | using ii = pair; 21 | using vi = vector; 22 | 23 | const int N = 1e5 + 5, MOD = 1e9 + 7, INF = 1e9 + 5; 24 | int n, q, l; 25 | vi g[N], st[N]; 26 | int c[N], depth[N], tin[N], tout[N], par[N][21]; 27 | bool ans[N]; 28 | int timer; 29 | 30 | struct query { 31 | int v, milk, idx; 32 | }; 33 | 34 | vector queries[N]; 35 | 36 | void dfs(int u = 0, int p = -1, int dep = 0) { 37 | tin[u] = timer++; 38 | depth[u] = dep; 39 | par[u][0] = (p == -1 ? 0 : p); 40 | for (int j = 1; j <= l; j++) par[u][j] = par[par[u][j - 1]][j - 1]; 41 | trav(v, g[u]) if (v != p) dfs(v, u, dep + 1); 42 | tout[u] = timer - 1; 43 | } 44 | 45 | bool isAnc(int x, int v) { 46 | return tin[x] <= tin[v] && tout[x] >= tout[v]; 47 | } 48 | 49 | int findLCA(int u, int v) { 50 | if (isAnc(u, v)) return u; 51 | if (isAnc(v, u)) return v; 52 | for (int j = l; j >= 0; j--) if (!isAnc(par[u][j], v)) u = par[u][j]; 53 | return par[u][0]; 54 | } 55 | 56 | bool valid(int x, int u, int v) { 57 | return depth[x] >= depth[u] && depth[x] <= depth[v]; 58 | } 59 | 60 | void dfs2(int u = 0, int p = -1) { 61 | st[c[u]].pb(u); 62 | trav(qry, queries[u]) { 63 | int v = qry.v, req = qry.milk, idx = qry.idx; 64 | int lca = findLCA(u, v); 65 | if (st[req].empty()) continue; 66 | int last = st[req].back(); 67 | if (valid(last, lca, u)) ans[idx] = true; 68 | } 69 | trav(v, g[u]) if (v != p) dfs2(v, u); 70 | st[c[u]].pop_back(); 71 | } 72 | 73 | signed main() { 74 | FAST_IO; 75 | setIO("milkvisits.in", "milkvisits.out"); 76 | 77 | cin >> n >> q; 78 | l = ceil(log2(n)); 79 | for (int i = 0; i < n; i++) { 80 | cin >> c[i]; 81 | c[i]--; 82 | } 83 | for (int i = 0; i < n - 1; i++) { 84 | int u, v; 85 | cin >> u >> v; 86 | u--, v--; 87 | g[u].pb(v); 88 | g[v].pb(u); 89 | } 90 | for (int i = 0; i < q; i++) { 91 | int u, v, milk; 92 | cin >> u >> v >> milk; 93 | u--, v--, milk--; 94 | queries[u].eb(query{v, milk, i}); 95 | queries[v].eb(query{u, milk, i}); 96 | } 97 | dfs(); 98 | dfs2(); 99 | for (int i = 0; i < q; i++) cout << ans[i]; 100 | } 101 | -------------------------------------------------------------------------------- /YouTube/Parallel Binary Search/Meteors_Normal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | template 8 | struct fenwick_tree { 9 | int n; 10 | vector tree; 11 | 12 | fenwick_tree() {} 13 | 14 | fenwick_tree(int _n) { init(_n); } 15 | 16 | void init(int _n) { 17 | n = _n; 18 | tree.assign(n + 1, 0); 19 | } 20 | 21 | void build(const vector &a) { 22 | for (int i = 1; i <= n; i++) { 23 | int j = i + (i & -i); 24 | 25 | tree[i] += a[i - 1]; 26 | if (j <= n) tree[j] += tree[i]; 27 | } 28 | } 29 | 30 | void increment(int pos, T val) { 31 | for (int i = pos + 1; i <= n; i += i & -i) 32 | tree[i] += val; 33 | } 34 | 35 | T query(int pos) { 36 | T res = 0; 37 | 38 | for (int i = pos + 1; i > 0; i -= i & -i) 39 | res += tree[i]; 40 | 41 | return res; 42 | } 43 | 44 | T query(int l, int r) { return query(r) - query(l - 1); } 45 | }; 46 | 47 | const int MXN = 3e5 + 5; 48 | const long long INF = 1e15; 49 | int N, M, K; 50 | vector stations[MXN]; 51 | int meteors_req[MXN], ans[MXN], showers[MXN][3], L[MXN], R[MXN]; 52 | fenwick_tree meteors; 53 | 54 | void update(int l, int r, long long delta) { 55 | if (r < l) { 56 | update(0, r, delta); 57 | r = M - 1; 58 | } 59 | 60 | meteors.increment(l, delta); 61 | meteors.increment(r + 1, -delta); 62 | } 63 | 64 | signed main() { 65 | ios_base::sync_with_stdio(false); 66 | cin.tie(nullptr); 67 | 68 | cin >> N >> M; 69 | 70 | for (int i = 0; i < M; i++) { 71 | int x; 72 | cin >> x; 73 | x--; 74 | 75 | stations[x].push_back(i); 76 | } 77 | 78 | for (int i = 0; i < N; i++) 79 | cin >> meteors_req[i]; 80 | 81 | cin >> K; 82 | 83 | for (int i = 0; i < K; i++) { 84 | for (int j = 0; j < 3; j++) 85 | cin >> showers[i][j]; 86 | 87 | for (int j = 0; j < 2; j++) 88 | showers[i][j]--; 89 | } 90 | 91 | for (int i = 0; i < N; i++) { 92 | ans[i] = 1e9; 93 | L[i] = 0, R[i] = K - 1; 94 | } 95 | 96 | while (true) { 97 | vector queries[K]; 98 | 99 | bool all_answered = true; 100 | 101 | for (int i = 0; i < N; i++) { 102 | if (L[i] > R[i]) continue; 103 | 104 | all_answered = false; 105 | queries[(L[i] + R[i]) / 2].push_back(i); 106 | } 107 | 108 | if (all_answered) break; 109 | 110 | meteors.init(M + 5); 111 | 112 | for (int mid = 0; mid < K; mid++) { 113 | update(showers[mid][0], showers[mid][1], showers[mid][2]); 114 | 115 | for (const auto &state : queries[mid]) { 116 | long long gathered = 0; 117 | 118 | for (const auto &station : stations[state]) { 119 | gathered += meteors.query(station); 120 | if (gathered >= 1e18) break; 121 | } 122 | 123 | if (gathered >= meteors_req[state]) { 124 | ans[state] = min(ans[state], mid); 125 | R[state] = mid - 1; 126 | } else L[state] = mid + 1; 127 | } 128 | } 129 | } 130 | 131 | for (int i = 0; i < N; i++) { 132 | if (ans[i] < 1e9) cout << ans[i] + 1 << "\n"; 133 | else cout << "NIE\n"; 134 | } 135 | } -------------------------------------------------------------------------------- /YouTube/Parallel Binary Search/Meteors_DnC.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | template 8 | struct fenwick_tree { 9 | int n; 10 | vector tree; 11 | 12 | fenwick_tree() {} 13 | 14 | fenwick_tree(int _n) { init(_n); } 15 | 16 | void init(int _n) { 17 | n = _n; 18 | tree.assign(n + 1, 0); 19 | } 20 | 21 | void build(const vector &a) { 22 | for (int i = 1; i <= n; i++) { 23 | int j = i + (i & -i); 24 | 25 | tree[i] += a[i - 1]; 26 | if (j <= n) tree[j] += tree[i]; 27 | } 28 | } 29 | 30 | void increment(int pos, T val) { 31 | for (int i = pos + 1; i <= n; i += i & -i) 32 | tree[i] += val; 33 | } 34 | 35 | T query(int pos) { 36 | T res = 0; 37 | 38 | for (int i = pos + 1; i > 0; i -= i & -i) 39 | res += tree[i]; 40 | 41 | return res; 42 | } 43 | 44 | T query(int l, int r) { return query(r) - query(l - 1); } 45 | }; 46 | 47 | const int MXN = 3e5 + 5; 48 | const long long INF = 1e15; 49 | int N, M, K; 50 | vector stations[MXN]; 51 | int meteors_req[MXN], ans[MXN]; 52 | int showers[MXN][3]; 53 | fenwick_tree meteors; 54 | 55 | void update(int l, int r, long long delta) { 56 | if (r < l) { 57 | update(0, r, delta); 58 | r = M - 1; 59 | } 60 | 61 | meteors.increment(l, delta); 62 | meteors.increment(r + 1, -delta); 63 | } 64 | 65 | void parallel_binary_search(int l, int r, const vector &queries) { 66 | if (l > r || queries.empty()) return; 67 | 68 | int mid = (l + r) / 2; 69 | 70 | for (int i = l; i <= mid; i++) 71 | update(showers[i][0], showers[i][1], showers[i][2]); 72 | 73 | vector new_queries[2]; 74 | 75 | for (const auto &state : queries) { 76 | long long gathered = 0; 77 | 78 | for (const auto &station : stations[state]) { 79 | gathered += meteors.query(station); 80 | if (gathered >= 1e18) break; 81 | } 82 | 83 | if (gathered >= meteors_req[state]) { 84 | ans[state] = min(ans[state], mid); 85 | new_queries[0].push_back(state); 86 | } else new_queries[1].push_back(state); 87 | } 88 | 89 | parallel_binary_search(mid + 1, r, new_queries[1]); 90 | 91 | for (int i = l; i <= mid; i++) 92 | update(showers[i][0], showers[i][1], -showers[i][2]); 93 | 94 | parallel_binary_search(l, mid - 1, new_queries[0]); 95 | } 96 | 97 | signed main() { 98 | ios_base::sync_with_stdio(false); 99 | cin.tie(nullptr); 100 | 101 | cin >> N >> M; 102 | 103 | for (int i = 0; i < M; i++) { 104 | int x; 105 | cin >> x; 106 | x--; 107 | 108 | stations[x].push_back(i); 109 | } 110 | 111 | for (int i = 0; i < N; i++) 112 | cin >> meteors_req[i]; 113 | 114 | cin >> K; 115 | 116 | for (int i = 0; i < K; i++) { 117 | for (int j = 0; j < 3; j++) 118 | cin >> showers[i][j]; 119 | 120 | for (int j = 0; j < 2; j++) 121 | showers[i][j]--; 122 | } 123 | 124 | meteors.init(MXN); 125 | 126 | vector queries(N); 127 | iota(queries.begin(), queries.end(), 0); 128 | 129 | for (int i = 0; i < N; i++) 130 | ans[i] = 1e9; 131 | 132 | parallel_binary_search(0, K - 1, queries); 133 | 134 | for (int i = 0; i < N; i++) { 135 | if (ans[i] < 1e9) cout << ans[i] + 1 << "\n"; 136 | else cout << "NIE\n"; 137 | } 138 | } -------------------------------------------------------------------------------- /Data Structures/Segment Trees/SegmentTree_Lazy.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct segment_tree : public Modifier { 3 | /* 4 | Modifier Requires: 5 | 1. typename T : Data type used throughout the tree. 6 | 2. T identity_merge : Return element. 7 | 3. T identity_update : Lazy base value 8 | 4. bool range_each : tree[i] * range length? 9 | 5. T merge : Merging two segment tree nodes. 10 | 6. T update : Process for updating nodes. 11 | */ 12 | 13 | using T = typename Modifier::T; 14 | 15 | int n; 16 | vector a, tree, lazy; 17 | T identity_merge = Modifier::identity_merge; 18 | T identity_update = Modifier::identity_update; 19 | 20 | segment_tree(int _n = 0) { init(_n); } 21 | 22 | segment_tree(int _n, const vector &_a) { init(_n, _a); } 23 | 24 | void init(int _n) { 25 | n = _n; 26 | tree.assign(4 * n, identity_merge); 27 | lazy.assign(4 * n, identity_update); 28 | } 29 | 30 | void init(int _n, const vector &_a) { 31 | n = _n; 32 | tree.resize(4 * n); 33 | lazy.resize(4 * n); 34 | 35 | a = _a; 36 | build(1, 0, n - 1); 37 | } 38 | 39 | void build(int i, int l, int r) { 40 | lazy[i] = identity_update; 41 | 42 | if (l == r) { 43 | tree[i] = a[l]; 44 | return; 45 | } 46 | 47 | int mid = (l + r) / 2; 48 | 49 | build(2 * i, l, mid); 50 | build(2 * i + 1, mid + 1, r); 51 | 52 | tree[i] = Modifier::merge(tree[2 * i], tree[2 * i + 1]); 53 | } 54 | 55 | void propagate(int i, int l, int r) { 56 | if (lazy[i] == identity_update) return; 57 | 58 | tree[i] = Modifier::update(tree[i], lazy[i] * (Modifier::range_each ? (r - l + 1) : 1)); 59 | 60 | if (l != r) { 61 | lazy[2 * i] = Modifier::update(lazy[2 * i], lazy[i]); 62 | lazy[2 * i + 1] = Modifier::update(lazy[2 * i + 1], lazy[i]); 63 | } 64 | 65 | lazy[i] = identity_update; 66 | } 67 | 68 | void modify(int i, int l, int r, int ql, int qr, T val) { 69 | propagate(i, l, r); 70 | if (l > qr || r < ql) return; 71 | if (l >= ql && r <= qr) { 72 | lazy[i] = Modifier::update(lazy[i], val); 73 | propagate(i, l, r); 74 | return; 75 | } 76 | 77 | int mid = (l + r) / 2; 78 | 79 | modify(2 * i, l, mid, ql, qr, val); 80 | modify(2 * i + 1, mid + 1, r, ql, qr, val); 81 | 82 | tree[i] = Modifier::merge(tree[2 * i], tree[2 * i + 1]); 83 | } 84 | 85 | T query(int i, int l, int r, int ql, int qr) { 86 | propagate(i, l, r); 87 | if (l > qr || r < ql) return identity_merge; 88 | if (l >= ql && r <= qr) return tree[i]; 89 | 90 | int mid = (l + r) / 2; 91 | return Modifier::merge(query(2 * i, l, mid, ql, qr), query(2 * i + 1, mid + 1, r, ql, qr)); 92 | } 93 | 94 | void modify(int l, int r, T val) { modify(1, 0, n - 1, l, r, val); } 95 | 96 | T query(int l, int r) { return query(1, 0, n - 1, l, r); } 97 | 98 | T query(int pos) { return query(1, 0, n - 1, pos, pos); } 99 | }; 100 | 101 | // struct RARM { 102 | // using T = long long; 103 | 104 | // const T identity_merge = numeric_limits::max(); 105 | // const T identity_update = 0; 106 | // bool range_each = true; 107 | 108 | // T merge(const T &x, const T &y) { 109 | // return min(x, y); 110 | // }; 111 | 112 | // T update(const T &x, const T &y) { 113 | // return x + y; 114 | // }; 115 | // }; -------------------------------------------------------------------------------- /Data Structures/LiChaoTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct li_chao_min { 3 | static const T identity = numeric_limits::max(); 4 | 5 | struct Line { 6 | T m, c; 7 | 8 | Line() { 9 | m = 0; 10 | c = identity; 11 | } 12 | 13 | Line(T m, T c) : m(m), c(c) {} 14 | 15 | T val(T x) { return m * x + c; } 16 | }; 17 | 18 | struct Node { 19 | Line line; 20 | Node *lc, *rc; 21 | 22 | Node() : lc(0), rc(0) {} 23 | }; 24 | 25 | T L, R, eps; 26 | deque buffer; 27 | Node* root; 28 | 29 | Node* new_node() { 30 | buffer.emplace_back(); 31 | return &buffer.back(); 32 | } 33 | 34 | li_chao_min() {} 35 | 36 | li_chao_min(T _L, T _R, T _eps) { 37 | init(_L, _R, _eps); 38 | } 39 | 40 | void init(T _L, T _R, T _eps) { 41 | L = _L; 42 | R = _R; 43 | eps = _eps; 44 | 45 | root = new_node(); 46 | } 47 | 48 | void insert(Node* &cur, T l, T r, Line line) { 49 | if (!cur) { 50 | cur = new_node(); 51 | cur->line = line; 52 | return; 53 | } 54 | 55 | T mid = l + (r - l) / 2; 56 | if (r - l <= eps) return; 57 | 58 | if (line.val(mid) < cur->line.val(mid)) 59 | swap(line, cur->line); 60 | 61 | if (line.val(l) < cur->line.val(l)) insert(cur->lc, l, mid, line); 62 | else insert(cur->rc, mid + 1, r, line); 63 | } 64 | 65 | T query(Node* &cur, T l, T r, T x) { 66 | if (!cur) return identity; 67 | 68 | T mid = l + (r - l) / 2; 69 | T res = cur->line.val(x); 70 | if (r - l <= eps) return res; 71 | 72 | if (x <= mid) return min(res, query(cur->lc, l, mid, x)); 73 | else return min(res, query(cur->rc, mid + 1, r, x)); 74 | } 75 | 76 | void insert(T m, T c) { insert(root, L, R, Line(m, c)); } 77 | 78 | T query(T x) { return query(root, L, R, x); } 79 | }; 80 | 81 | template 82 | struct li_chao_max { 83 | static const T identity = numeric_limits::min(); 84 | 85 | struct Line { 86 | T m, c; 87 | 88 | Line() { 89 | m = 0; 90 | c = identity; 91 | } 92 | 93 | Line(T m, T c) : m(m), c(c) {} 94 | 95 | T val(T x) { return m * x + c; } 96 | }; 97 | 98 | struct Node { 99 | Line line; 100 | Node *lc, *rc; 101 | 102 | Node() : lc(0), rc(0) {} 103 | }; 104 | 105 | T L, R, eps; 106 | deque buffer; 107 | Node* root; 108 | 109 | Node* new_node() { 110 | buffer.emplace_back(); 111 | return &buffer.back(); 112 | } 113 | 114 | li_chao_max() {} 115 | 116 | li_chao_max(T _L, T _R, T _eps) { 117 | init(_L, _R, _eps); 118 | } 119 | 120 | void init(T _L, T _R, T _eps) { 121 | L = _L; 122 | R = _R; 123 | eps = _eps; 124 | 125 | root = new_node(); 126 | } 127 | 128 | void insert(Node* &cur, T l, T r, Line line) { 129 | if (!cur) { 130 | cur = new_node(); 131 | cur->line = line; 132 | return; 133 | } 134 | 135 | T mid = l + (r - l) / 2; 136 | if (r - l <= eps) return; 137 | 138 | if (line.val(mid) > cur->line.val(mid)) 139 | swap(line, cur->line); 140 | 141 | if (line.val(l) > cur->line.val(l)) insert(cur->lc, l, mid, line); 142 | else insert(cur->rc, mid + 1, r, line); 143 | } 144 | 145 | T query(Node* &cur, T l, T r, T x) { 146 | if (!cur) return identity; 147 | 148 | T mid = l + (r - l) / 2; 149 | T res = cur->line.val(x); 150 | if (r - l <= eps) return res; 151 | 152 | if (x <= mid) return max(res, query(cur->lc, l, mid, x)); 153 | else return max(res, query(cur->rc, mid + 1, r, x)); 154 | } 155 | 156 | void insert(T m, T c) { insert(root, L, R, Line(m, c)); } 157 | 158 | T query(T x) { return query(root, L, R, x); } 159 | }; -------------------------------------------------------------------------------- /Data Structures/PersistentCHT.cpp: -------------------------------------------------------------------------------- 1 | // CEOI 2009 Harbingers 2 | // https://oj.uz/problem/view/CEOI09_harbingers 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | void dbg_out() { cerr << endl; } 23 | template 24 | void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); } 25 | #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) 26 | 27 | #define rng_init mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) 28 | #define rng_seed(x) mt19937 rng(x) 29 | #define all(x) (x).begin(), (x).end() 30 | #define sz(x) (int) (x).size() 31 | #define int int64_t 32 | 33 | const int MXN = 1e5 + 5, INF = 1e18; 34 | vector> g[MXN]; 35 | int S[MXN], V[MXN], version[MXN], ans[MXN]; 36 | int last_version; 37 | 38 | struct Line { 39 | int m, c; 40 | 41 | Line() { 42 | m = 0; 43 | c = INF; 44 | } 45 | 46 | Line(int m, int c) : m(m), c(c) {} 47 | 48 | int val(int x) { return m * x + c; } 49 | }; 50 | 51 | struct Node { 52 | Line line; 53 | Node *lc, *rc; 54 | 55 | Node() : lc(0), rc(0) {} 56 | }; 57 | 58 | deque buffer; 59 | deque root; 60 | 61 | Node* new_node() { 62 | buffer.emplace_back(); 63 | return &buffer.back(); 64 | } 65 | 66 | void modify(Node* &prev, Node* &cur, int l, int r, Line new_line) { 67 | if (!prev) { 68 | cur->line = new_line; 69 | return; 70 | } 71 | 72 | cur->line = prev->line; 73 | 74 | if (r - l <= 0) return; 75 | 76 | cur->lc = prev->lc; 77 | cur->rc = prev->rc; 78 | 79 | int mid = l + (r - l) / 2; 80 | 81 | if (new_line.val(mid) < cur->line.val(mid)) 82 | swap(cur->line, new_line); 83 | 84 | if (new_line.val(l) < cur->line.val(l)) { 85 | cur->lc = new_node(); 86 | modify(prev->lc, cur->lc, l, mid, new_line); 87 | } else { 88 | cur->rc = new_node(); 89 | modify(prev->rc, cur->rc, mid + 1, r, new_line); 90 | } 91 | } 92 | 93 | int query(Node* &cur, int l, int r, int x) { 94 | if (!cur) return INF; 95 | 96 | int res = cur->line.val(x); 97 | if (r - l <= 0) return res; 98 | 99 | int mid = l + (r - l) / 2; 100 | if (x <= mid) return min(res, query(cur->lc, l, mid, x)); 101 | else return min(res, query(cur->rc, mid + 1, r, x)); 102 | } 103 | 104 | void modify(int modify_version, int m, int c) { 105 | root.emplace_back(new_node()); 106 | modify(root[modify_version], root[last_version], 0, 1000000000, Line(m, c)); 107 | } 108 | 109 | int query(int qry_version, int x) { 110 | return query(root[qry_version], 0, 1000000000, x); 111 | } 112 | 113 | void dfs(int u, int p, int dist) { 114 | version[u] = ++last_version; 115 | 116 | ans[u] = min(dist * V[u] + S[u], query(version[p], V[u]) + dist * V[u] + S[u]); 117 | modify(version[p], -dist, ans[u]); 118 | 119 | for (const auto &[v, d] : g[u]) { 120 | if (v == p) continue; 121 | dfs(v, u, dist + d); 122 | } 123 | } 124 | 125 | void solve() { 126 | int N; 127 | cin >> N; 128 | 129 | for (int i = 0; i < N - 1; i++) { 130 | int u, v, d; 131 | cin >> u >> v >> d; 132 | 133 | g[u].emplace_back(v, d); 134 | g[v].emplace_back(u, d); 135 | } 136 | 137 | for (int i = 2; i <= N; i++) 138 | cin >> S[i] >> V[i]; 139 | 140 | root.emplace_back(new_node()); 141 | buffer[0].line.c = 0; 142 | version[1] = 0; 143 | 144 | for (const auto &[v, d] : g[1]) { 145 | dfs(v, 1, d); 146 | } 147 | 148 | for (int i = 2; i <= N; i++) 149 | cout << ans[i] << " "; 150 | } 151 | 152 | signed main() { 153 | ios_base::sync_with_stdio(false); 154 | cin.tie(nullptr); 155 | 156 | int TC = 1; 157 | // cin >> TC; 158 | while (TC--) solve(); 159 | } 160 | -------------------------------------------------------------------------------- /USACO/2019/February/Gold/P1_CowLand.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * USACO 2019 February Contest, Gold 4 | * Problem 1. Cow Land 5 | * Problem Link: http://www.usaco.org/index.php?page=viewproblem2&cpid=921 6 | */ 7 | #include 8 | 9 | #define FAST_IO ios_base::sync_with_stdio(false), cin.tie(nullptr) 10 | #define setIO(i, o) freopen(i, "r", stdin), freopen(o, "w", stdout) 11 | #define pb(x) push_back(x) 12 | #define eb(x...) emplace_back(x) 13 | #define all(x) (x).begin(), (x).end() 14 | #define sz(x) (int) (x).size() 15 | #define lc(i) 2*i 16 | #define rc(i) 2*i+1 17 | //#define int long long 18 | using namespace std; 19 | using ii = pair; 20 | using vii = vector; 21 | using vi = vector; 22 | using vvi = vector; 23 | using vb = vector; 24 | using vvb = vector; 25 | 26 | const int N = 1e5 + 5, MOD = 1e9 + 7, INF = 1e9 + 5; 27 | vi g[N]; 28 | int a[N]; 29 | 30 | struct SegmentTree { 31 | int n; 32 | vector a, t, lazy; 33 | 34 | void init(int x) { 35 | n = x; 36 | t.assign(4 * n, 0); 37 | lazy.assign(4 * n, 0); 38 | } 39 | 40 | void init(int x, vector y) { 41 | n = x; 42 | a = y; 43 | t.resize(4 * n); 44 | lazy.assign(4 * n, 0); 45 | build(1, 0, n - 1); 46 | } 47 | 48 | int merge(int x, int y) { return x ^ y; } 49 | 50 | int upd(int x, int y) { return x ^ y; } 51 | 52 | void build(int i, int l, int r) { 53 | if (l == r) { 54 | t[i] = a[l]; 55 | return; 56 | } 57 | int mid = (l + r) / 2; 58 | build(lc(i), l, mid); 59 | build(rc(i), mid + 1, r); 60 | t[i] = merge(t[lc(i)], t[rc(i)]); 61 | } 62 | 63 | void push(int i, int l, int r) { 64 | t[i] = upd(t[i], lazy[i]); 65 | if (l != r) { 66 | lazy[lc(i)] = upd(lazy[lc(i)], lazy[i]); 67 | lazy[rc(i)] = upd(lazy[rc(i)], lazy[i]); 68 | } 69 | lazy[i] = 0; 70 | } 71 | 72 | void modify(int i, int l, int r, int ql, int qr, int val) { 73 | if (l > qr || r < ql) return; 74 | if (lazy[i] != 0) push(i, l, r); 75 | if (l >= ql && r <= qr) { 76 | lazy[i] = upd(lazy[i], val); 77 | push(i, l, r); 78 | return; 79 | } 80 | int mid = (l + r) / 2; 81 | modify(lc(i), l, mid, ql, qr, val); 82 | modify(rc(i), mid + 1, r, ql, qr, val); 83 | t[i] = merge(t[lc(i)], t[rc(i)]); 84 | } 85 | 86 | int query(int i, int l, int r, int ql, int qr) { 87 | if (l > qr || r < ql) return 0; 88 | if (lazy[i] != 0) push(i, l, r); 89 | if (l >= ql && r <= qr) return t[i]; 90 | int mid = (l + r) / 2; 91 | int resL = query(lc(i), l, mid, ql, qr); 92 | int resR = query(rc(i), mid + 1, r, ql, qr); 93 | return merge(resL, resR); 94 | } 95 | 96 | void modify(int l, int r, int val) { modify(1, 0, n - 1, l, r, val); } 97 | 98 | void modify(int pos, int val) { modify(1, 0, n - 1, pos, pos, val); } 99 | 100 | int query(int l, int r) { return query(1, 0, n - 1, l, r); } 101 | 102 | int query(int pos) { return query(1, 0, n - 1, pos, pos); } 103 | }; 104 | 105 | struct BinLiftLCA { 106 | int n, k, timer; 107 | vi tin, tout; 108 | vector> par; 109 | 110 | void init(int x) { 111 | n = x; 112 | k = ceil(log2(n)); 113 | timer = 0; 114 | tin.resize(n); 115 | tout.resize(n); 116 | par.assign(n, vector(k + 1, 0)); 117 | dfs(); 118 | } 119 | 120 | void dfs(int u = 0, int p = -1) { 121 | tin[u] = timer++; 122 | par[u][0] = (p == -1 ? 0 : p); 123 | for (int j = 1; j <= k; j++) par[u][j] = par[par[u][j - 1]][j - 1]; 124 | for (const auto &v: g[u]) if (v != p) dfs(v, u); 125 | tout[u] = timer - 1; 126 | } 127 | 128 | bool isAnc(int x, int v) { 129 | return tin[x] <= tin[v] && tout[x] >= tout[v]; 130 | } 131 | 132 | int query(int u, int v) { 133 | if (isAnc(u, v)) return u; 134 | if (isAnc(v, u)) return v; 135 | for (int j = k; j >= 0; j--) if (!isAnc(par[u][j], v)) u = par[u][j]; 136 | return par[u][0]; 137 | } 138 | }; 139 | 140 | signed main() { 141 | FAST_IO; 142 | #ifdef arujbansal_local 143 | setIO("input.txt", "output.txt"); 144 | #endif 145 | #ifndef arujbansal_local 146 | setIO("cowland.in", "cowland.out"); 147 | #endif 148 | 149 | int n, q; 150 | cin >> n >> q; 151 | for (int i = 0; i < n; i++) cin >> a[i]; 152 | for (int i = 0; i < n - 1; i++) { 153 | int u, v; 154 | cin >> u >> v; 155 | u--, v--; 156 | g[u].pb(v); 157 | g[v].pb(u); 158 | } 159 | BinLiftLCA lca; 160 | lca.init(n); 161 | SegmentTree seg; 162 | seg.init(lca.timer); 163 | for (int i = 0; i < n; i++) seg.modify(lca.tin[i], lca.tout[i], a[i]); 164 | while (q--) { 165 | int type; 166 | cin >> type; 167 | if (type == 1) { 168 | int pos, val; 169 | cin >> pos >> val; 170 | pos--; 171 | seg.modify(lca.tin[pos], lca.tout[pos], a[pos] ^ val); 172 | a[pos] = val; 173 | } else { 174 | int u, v; 175 | cin >> u >> v; 176 | u--, v--; 177 | cout << (seg.query(lca.tin[u]) ^ seg.query(lca.tin[v]) ^ a[lca.query(u, v)]) << "\n"; 178 | } 179 | } 180 | } --------------------------------------------------------------------------------