Skip to content
Snippets Groups Projects
Commit f7366924 authored by Bruno Freitas Tissei's avatar Bruno Freitas Tissei
Browse files

Fix lazy seg tree

parent 6194157c
No related branches found
No related tags found
No related merge requests found
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
int N, tree[4 * MAX], lazy[4 * MAX], v[MAX]; int N, tree[4 * MAX], lazy[4 * MAX], v[MAX];
// Build tree with elements from v // Builds tree with elements from v
void build_tree(int node = 1, int a = 0, int b = N) { void build(int node = 1, int a = 0, int b = n) {
if (a > b) if (a > b)
return; return;
if (a == b) { if (a == b) {
...@@ -20,14 +20,16 @@ void build_tree(int node = 1, int a = 0, int b = N) { ...@@ -20,14 +20,16 @@ void build_tree(int node = 1, int a = 0, int b = N) {
return; return;
} }
build_tree(node * 2, a, (a + b) / 2); build(node * 2, a, (a + b) / 2);
build_tree(node * 2 + 1, 1 + (a + b) / 2, b); build(node * 2 + 1, (a + b) / 2 + 1, b);
tree[node] = tree[node * 2] + tree[node * 2 + 1]; tree[node] = tree[node * 2] + tree[node * 2 + 1];
} }
void push(int node, int val) { // Propagates value to tree and through lazy tree
tree[node] += value; void push(int node, int a, int b, int val) {
tree[node] += val;
// tree[node] += (b - a + 1) * val; (for Range Sum Query)
if (a != b) { if (a != b) {
lazy[node * 2] += val; lazy[node * 2] += val;
...@@ -38,39 +40,37 @@ void push(int node, int val) { ...@@ -38,39 +40,37 @@ void push(int node, int val) {
} }
// Update segment [i,j] by adding value val // Updates segment [i,j] by adding value val
void update_tree(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) {
if (lazy[node] != 0) if (lazy[node] != 0)
push(node, lazy[node]); push(node, a, b, lazy[node]);
if (a > b or a > j or b < i)
if (a > b || a > j || b < i)
return; return;
if (a >= i && b <= j) { if (a >= i and b <= j) {
push(node, val); push(node, a, b, val);
return; return;
} }
update_tree(i, j, node * 2, a, (a + b) / 2); update(i, j, val, node * 2, a, (a + b) / 2);
update_tree(i, j, node * 2 + 1, 1 + (a + b) / 2, b); update(i, j, val, node * 2 + 1, (a + b) / 2 + 1, b);
tree[node] = tree[node * 2] + tree[node * 2 + 1]; tree[node] = tree[node * 2] + tree[node * 2 + 1];
} }
// Return sum of [i,j] // Returns sum of [i,j]
int query_tree(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) {
if (a > b || a > j || b < i) if (a > b || a > j || b < i)
return 0; return 0;
if (lazy[node] != 0) { if (lazy[node])
push(node, val); push(node, a, b, lazy[node]);
}
if (a >= i && b <= j) if (a >= i and b <= j)
return tree[node]; return tree[node];
int q1 = query_tree(i, j, node * 2, a, (a + b) / 2); int q1 = query(i, j, node * 2, a, (a + b) / 2);
int q2 = query_tree(i, j, node * 2 + 1, 1 + (a + b) / 2, b); int q2 = query(i, j, node * 2 + 1, (a + b) / 2 + 1, b);
return q1 + q2; return q1 + q2;
} }
#include <bits/stdc++.h>
#define MAX 101010
#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))
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
typedef struct elem {
int h, e, r;
elem() : h(0), e(0), r(0) {}
elem(int h, int e, int r) : h(h), e(e), r(r) {}
elem operator+(const elem &x) {
return elem(h + x.h, e + x.e, r + x.r);
}
void change(int n) {
int a = h, b = e, c = r;
if (n % 3 == 1) {
e = a;
r = b;
h = c;
} else if (n % 3 == 2) {
e = c;
r = a;
h = b;
}
}
} elem;
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;
if (a == b) {
tree[node] = v[a];
return;
}
build(node * 2, a, (a + b) / 2);
build(node * 2 + 1, (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);
if (a != b) {
lazy[node * 2] += val;
lazy[node * 2 + 1] += val;
}
lazy[node] = 0;
}
void update(int i, int j, int node = 1, int a = 0, int b = n) {
if (lazy[node] != 0)
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;
}
update(i, j, node * 2, a, (a + b) / 2);
update(i, j, node * 2 + 1, (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) {
if (a > b || a > j || b < i)
return elem();
if (lazy[node])
push(node, a, b, lazy[node]);
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);
return q1 + q2;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int 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) {
v[i].h = 1;
v[i].e = v[i].r = 0;
}
build();
for (int i = 0; i < m; ++i) {
char op;
int a, b; cin >> op >> a >> b;
if (op == 'C') {
elem x = query(a - 1, b - 1);
cout << x.h << " " << x.e << " " << x.r << ende;
} else {
update(a - 1, b - 1);
}
}
cout << ende;
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment