F - Sequence operation
题解:这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,这个有两个地方要注意一下,一个是取反的lazy标志,每次取反都是对1取异或,还有一个也是这个取反的lazy标志,这个标志再第一种操作之后要进行消除。
#include <cstdio> #include <cstdlib> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <string> #include <iostream> #include <stack> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e6 + 100; struct node { int sum; int max_sub, max_zero; int l, r, len; int lazy1, lazy2; int max_prezero, max_lastzero; int max_preone, max_lastone; }tree[maxn * 4]; int a[maxn]; void push_up(int id) { tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum; tree[id].max_preone = tree[id << 1].max_preone; if (tree[id].max_preone == tree[id << 1].len) tree[id].max_preone += tree[id << 1 | 1].max_preone; tree[id].max_lastone = tree[id << 1 | 1].max_lastone; if (tree[id].max_lastone == tree[id << 1 | 1].len) tree[id].max_lastone += tree[id << 1].max_lastone; tree[id].max_sub = max(tree[id << 1].max_lastone + tree[id << 1 | 1].max_preone, max(tree[id << 1].max_sub, tree[id << 1 | 1].max_sub)); tree[id].max_prezero = tree[id << 1].max_prezero; if (tree[id].max_prezero == tree[id << 1].len) tree[id].max_prezero += tree[id << 1 | 1].max_prezero; tree[id].max_lastzero = tree[id << 1 | 1].max_lastzero; if (tree[id].max_lastzero == tree[id << 1 | 1].len) tree[id].max_lastzero += tree[id << 1].max_lastzero; tree[id].max_zero = max(tree[id << 1].max_lastzero + tree[id << 1 | 1].max_prezero, max(tree[id << 1].max_zero, tree[id << 1 | 1].max_zero)); return; } void chang1(int id, int val) { if (val) { tree[id].sum = tree[id].len; tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = tree[id].len; tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = 0; } else { tree[id].sum = 0; tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = 0; tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = tree[id].len; } } void chang2(int id) { swap(tree[id].max_sub, tree[id].max_zero); swap(tree[id].max_prezero, tree[id].max_preone); swap(tree[id].max_lastone, tree[id].max_lastzero); tree[id].sum = tree[id].len - tree[id].sum; } void push_down(int id) { if (tree[id].lazy1) { chang1(id << 1, tree[id].lazy1 - 1); chang1(id << 1 | 1, tree[id].lazy1 - 1); tree[id << 1].lazy1 = tree[id << 1 | 1].lazy1 = tree[id].lazy1; tree[id << 1].lazy2 =tree[id << 1 | 1].lazy2 = 0; tree[id].lazy1 = 0; } if (tree[id].lazy2) { chang2(id << 1); chang2(id << 1 | 1); tree[id << 1].lazy2 ^= 1; tree[id << 1 | 1].lazy2 ^= 1; tree[id].lazy2 = 0; } } void build(int id, int l, int r) { tree[id].l = l; tree[id].r = r; tree[id].lazy1 = 0; tree[id].lazy2 = 0; tree[id].len = r - l + 1; if (l == r) { if (a[l]) chang1(id, 1); else chang1(id, 0); return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); push_up(id); } void update_change(int id, int l, int r, int z) { if (l <= tree[id].l&&r >= tree[id].r) { chang1(id, z); tree[id].lazy1 = z + 1; tree[id].lazy2 = 0; return; } push_down(id); int mid = (tree[id].l + tree[id].r) >> 1; if (l <= mid) update_change(id << 1, l, r, z); if (r > mid) update_change(id << 1 | 1, l, r, z); push_up(id); } void update_trans(int id, int l, int r) { if (l <= tree[id].l&&r >= tree[id].r) { tree[id].lazy2 ^= 1; chang2(id); return; } push_down(id); int mid = (tree[id].l + tree[id].r) >> 1; if (l <= mid) update_trans(id << 1, l, r); if (r > mid) update_trans(id << 1 | 1, l, r); push_up(id); } int query_sum(int id, int l, int r) { if (l <= tree[id].l&&r >= tree[id].r) { return tree[id].sum; } push_down(id); int mid = (tree[id].l + tree[id].r) >> 1, ans = 0; if (l <= mid) ans += query_sum(id << 1, l, r); if (r > mid) ans += query_sum(id << 1 | 1, l, r); return ans; } int query(int id, int l, int r) { int ans = 0; if (l <= tree[id].l&&r >= tree[id].r) { return tree[id].max_sub; } push_down(id); int mid = (tree[id].l + tree[id].r) >> 1; if (l <= mid) ans = max(ans, query(id << 1, l, r)); if (r > mid) ans = max(ans, query(id << 1 | 1, l, r)); ans = max(ans, min(mid - l + 1, tree[id << 1].max_lastone) + min(r - mid, tree[id << 1 | 1].max_preone)); return ans; } int main() { int t; cin >> t; while (t--) { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); build(1, 1, n); while (m--) { int c, x, y; scanf("%d%d%d", &c, &x, &y); if (c == 0) update_change(1, x + 1, y + 1, 0); if (c == 1) update_change(1, x + 1, y + 1, 1); if (c == 2) update_trans(1, x + 1, y + 1); if (c == 3) { int ans = query_sum(1, x + 1, y + 1); printf("%d\n", ans); } if (c == 4) { int ans = query(1, x + 1, y + 1); printf("%d\n", ans); } } } return 0; }
来源:https://www.cnblogs.com/EchoZQN/p/10809778.html