diff --git a/algorithms/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp index 1fac1b08b73a0d4545b36689698dd37b8293f0d3..e53f12e748a9474c15b136ca85e1819ef6e6e746 100644 --- a/algorithms/structure/lazy_segment_tree.cpp +++ b/algorithms/structure/lazy_segment_tree.cpp @@ -8,10 +8,15 @@ * Complexity (Space): O(n) */ -int N, tree[4 * MAX], lazy[4 * MAX], v[MAX]; +int N; +int v[MAX]; +int tree[4 * MAX], lazy[4 * MAX]; -// Builds tree with elements from v -void build(int node = 1, int a = 0, int b = n) { +#define left(x) ((x << 1)) +#define right(x) ((x << 1) + 1) + +// Builds tree with elements from v (0-indexed) +void build(int node = 1, int a = 0, int b = N - 1) { if (a > b) return; @@ -20,8 +25,8 @@ void build(int node = 1, int a = 0, int b = n) { return; } - build(node * 2, a, (a + b) / 2); - build(node * 2 + 1, (a + b) / 2 + 1, b); + build(left(node), a, (a + b) / 2); + build(right(node), (a + b) / 2 + 1, b); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } @@ -32,8 +37,8 @@ void push(int node, int a, int b, int val) { // tree[node] += (b - a + 1) * val; (for Range Sum Query) if (a != b) { - lazy[node * 2] += val; - lazy[node * 2 + 1] += val; + lazy[left(node)] += val; + lazy[right(node)] += val; } lazy[node] = 0; @@ -41,7 +46,7 @@ void push(int node, int a, int b, int val) { // Updates segment [i,j] by adding value val -void update(int i, int j, int val, int node = 1, int a = 0, int b = n) { +void update(int i, int j, int val, int node = 1, int a = 0, int b = N - 1) { if (lazy[node] != 0) push(node, a, b, lazy[node]); @@ -53,14 +58,14 @@ void update(int i, int j, int val, int node = 1, int a = 0, int b = n) { return; } - update(i, j, val, node * 2, a, (a + b) / 2); - update(i, j, val, node * 2 + 1, (a + b) / 2 + 1, b); + update(i, j, val, left(node), a, (a + b) / 2); + update(i, j, val, right(node), (a + b) / 2 + 1, b); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } // Returns sum of [i,j] -int query(int i, int j, int node = 1, int a = 0, int b = n) { +int query(int i, int j, int node = 1, int a = 0, int b = N - 1) { if (a > b || a > j || b < i) return 0; @@ -70,7 +75,7 @@ int query(int i, int j, int node = 1, int a = 0, int b = n) { if (a >= i and b <= j) return tree[node]; - int q1 = query(i, j, node * 2, a, (a + b) / 2); - int q2 = query(i, j, node * 2 + 1, (a + b) / 2 + 1, b); + int q1 = query(i, j, left(node), a, (a + b) / 2); + int q2 = query(i, j, right(node), (a + b) / 2 + 1, b); return q1 + q2; } diff --git a/contests/Cadernaveis/URI1477.cpp b/contests/Cadernaveis/URI1477.cpp index 3790a06edfbe4d3c30a466825723bbcbe38b4d8a..289d7ed2e40cbb4aaa937332baffd85a862f2684 100644 --- a/contests/Cadernaveis/URI1477.cpp +++ b/contests/Cadernaveis/URI1477.cpp @@ -46,56 +46,61 @@ typedef struct elem { } elem; -int n; +int N; elem v[MAX]; elem tree[MAX * 4]; int lazy[MAX * 4]; -void build(int node = 1, int a = 0, int b = n) { - if (a > b) return; +#define left(x) ((x << 1)) +#define right(x) ((x << 1) + 1) + +void build(int node = 1, int a = 0, int b = N - 1) { + if (a > b) + return; if (a == b) { tree[node] = v[a]; return; } - build(node * 2, a, (a + b) / 2); - build(node * 2 + 1, (a + b) / 2 + 1, b); + build(left(node), a, (a + b) / 2); + build(right(node), (a + b) / 2 + 1, b); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } void push(int node, int a, int b, int val) { tree[node].change(val); + // tree[node] += (b - a + 1) * val; (for Range Sum Query) if (a != b) { - lazy[node * 2] += val; - lazy[node * 2 + 1] += val; + lazy[left(node)] += val; + lazy[right(node)] += val; } lazy[node] = 0; } -void update(int i, int j, int node = 1, int a = 0, int b = n) { +void update(int i, int j, int node = 1, int a = 0, int b = N - 1) { if (lazy[node] != 0) - push(node, a, b, lazy[node]); + push(node, a, b, lazy[node]); if (a > b or a > j or b < i) return; if (a >= i and b <= j) { push(node, a, b, 1); - return; + return; } - update(i, j, node * 2, a, (a + b) / 2); - update(i, j, node * 2 + 1, (a + b) / 2 + 1, b); + update(i, j, left(node), a, (a + b) / 2); + update(i, j, right(node), (a + b) / 2 + 1, b); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } -elem query(int i, int j, int node = 1, int a = 0, int b = n) { +elem query(int i, int j, int node = 1, int a = 0, int b = N - 1) { if (a > b || a > j || b < i) return elem(); @@ -105,8 +110,8 @@ elem query(int i, int j, int node = 1, int a = 0, int b = n) { if (a >= i and b <= j) return tree[node]; - elem q1 = query(i, j, node * 2, a, (a + b) / 2); - elem q2 = query(i, j, node * 2 + 1, (a + b) / 2 + 1, b); + elem q1 = query(i, j, left(node), a, (a + b) / 2); + elem q2 = query(i, j, right(node), (a + b) / 2 + 1, b); return q1 + q2; } @@ -116,13 +121,13 @@ int main() { cin.tie(0); int m; - while (cin >> n >> m) { + while (cin >> N >> m) { for (int i = 0; i < MAX * 4; ++i) { tree[i] = elem(); lazy[i] = 0; } - for (int i = 0; i < n; ++i) { + for (int i = 0; i < N; ++i) { v[i].h = 1; v[i].e = v[i].r = 0; } diff --git a/problems/a_simple_task.cpp b/problems/a_simple_task.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3982502c7acc2841ca0cc2ffded5803d9736c5b --- /dev/null +++ b/problems/a_simple_task.cpp @@ -0,0 +1,155 @@ +#include <bits/stdc++.h> + +#define MAX 100001 +#define EPS 1e-6 +#define MOD 1000000007 +#define inf 0x3f3f3f3f +#define llinf 0x3f3f3f3f3f3f3f3f + +#define fi first +#define se second +#define sz size() +#define pb push_back +#define ende '\n' + +#define all(x) (x).begin(), (x).end() +#define rall(x) (x).rbegin(), (x).rend() +#define mset(x, y) memset(&x, (y), sizeof(x)) + +#define left(x) ((x << 1)) +#define right(x) ((x << 1) + 1) + +using namespace std; + +typedef long long ll; +typedef pair<int,int> ii; + +int N, q; +int tree[4 * MAX][26], lazy[4 * MAX][26]; + +string s; + +void build(int node = 1, int a = 0, int b = N-1) { + if (a > b) + return; + + if (a == b) { + tree[node][s[a] - 'a'] = 1; + return; + } + + build(left(node), a, (a + b) / 2); + build(right(node), (a + b) / 2 + 1, b); + + for (int i = 0; i < 26; ++i) + tree[node][i] = tree[left(node)][i] + tree[right(node)][i]; +} + + +void push(int let, int node, int a, int b, int val) { + tree[node][let] = (b - a + 1) * val; + + if (a != b) { + lazy[left(node)][let] = val; + lazy[right(node)][let] = val; + } + + lazy[node][let] = -1; +} + + +void update(int let, int i, int j, int val, int node = 1, int a = 0, int b = N-1) { + if (lazy[node][let] != -1) + push(let, node, a, b, lazy[node][let]); + + if (a > b or a > j or b < i) + return; + + if (i <= a and b <= j) { + push(let, node, a, b, val); + return; + } + + update(let, i, j, val, left(node), a, (a + b) / 2); + update(let, i, j, val, right(node), (a + b) / 2 + 1, b); + tree[node][let] = tree[left(node)][let] + tree[right(node)][let]; +} + + +int query(int let, int i, int j, int node = 1, int a = 0, int b = N-1) { + if (a > b || a > j || b < i) + return 0; + + if (lazy[node][let] != -1) + push(let, node, a, b, lazy[node][let]); + + if (a >= i and b <= j) + return tree[node][let]; + + int q1 = query(let, i, j, left(node), a, (a + b) / 2); + int q2 = query(let, i, j, right(node), (a + b) / 2 + 1, b); + return q1 + q2; +} + + +void get_ans(int let, string &ans, int node = 1, int l = 0, int r = N-1) { + if (lazy[node][let] != -1) + push(let, node, l, r, lazy[node][let]); + + if (!tree[node][let]) + return; + + if (l == r) { + ans[l] = let + 'a'; + return; + } + + get_ans(let, ans, left(node), l, (l+r)/2); + get_ans(let, ans, right(node), (l+r)/2 + 1, r); +} + + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + cin >> N >> q; + cin >> s; + + build(); + mset(lazy, -1); + + vector<int> cnt(26); + for (int i = 0; i < q; ++i) { + int a, b, k; cin >> a >> b >> k; + a--, b--; + for (int j = 0; j < 26; ++j) { + cnt[j] = query(j, a, b); + if (cnt[j]) update(j, a, b, 0); + } + + if (k) { + int bord = a; + for (int j = 0; j < 26; ++j) + if (cnt[j]) { + update(j, bord, bord + cnt[j] - 1, 1); + bord += cnt[j]; + } + } else { + int bord = a; + for (int j = 25; j >= 0; --j) + if (cnt[j]) { + update(j, bord, bord + cnt[j] - 1, 1); + bord += cnt[j]; + } + } + + fill(all(cnt), 0); + } + + string ans(N, '-'); + for (int j = 0; j < 26; ++j) + get_ans(j, ans); + cout << ans << ende; + return 0; +}