HDU 3397 sequence operation
Question Link
Question: Given A 01 sequence, there are 5 Operations
0 a B [A. B] is set to 0
1 a B [a, B] is set to 1
2 a B [a, B] the range 0 is changed to 1, 1 to 0
3 a B: query the number of [a, B] ranges 1.
4 a B query the maximum length of [a, B] consecutive 1
Idea: Merge line segments of a line segment tree. Two delay tags must be set to 01, one is flipped, and the longest value 0 and 1 on the left and the longest value 0 and 1 on the right must be recorded due to 4 operations, the maximum range is 0 and 1, and then the range can be merged.
Code:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define lson(x) ((x<<1)+1)#define rson(x) ((x<<1)+2)const int N = 100005;int t, n, m;struct Node {int l, r, sum[3][2], num;int setv, flip;Node() {setv = -1;flip = 0;}int size() {return r - l + 1;}void gao1(int v) {setv = v;num = v * (r - l + 1);for (int i = 0; i < 3; i++) {sum[i][v] = r - l + 1;sum[i][!v] = 0;}flip = 0;}void gao2() {flip ^= 1;for (int i = 0; i < 3; i++)swap(sum[i][0], sum[i][1]);num = r - l + 1 - num;}} node[N * 4];Node merge(Node lson, Node rson) {Node x;x.l = lson.l; x.r = rson.r;for (int i = 0; i < 2; i++) {x.sum[0][i] = lson.sum[0][i];x.sum[1][i] = rson.sum[1][i];x.sum[2][i] = max(lson.sum[2][i], rson.sum[2][i]);if (lson.sum[0][i] == lson.size())x.sum[0][i] += rson.sum[0][i];if (rson.sum[1][i] == rson.size())x.sum[1][i] += lson.sum[1][i];x.sum[2][i] = max(x.sum[2][i], lson.sum[1][i] + rson.sum[0][i]);}x.num = lson.num + rson.num;return x;}void pushup(int x) {node[x] = merge(node[lson(x)], node[rson(x)]);}void pushdown(int x) {if (node[x].setv != -1) {node[lson(x)].gao1(node[x].setv);node[rson(x)].gao1(node[x].setv);node[x].setv = -1;}if (node[x].flip) {node[lson(x)].gao2();node[rson(x)].gao2();node[x].flip = 0;}}void build(int l, int r, int x = 0) {node[x].l = l; node[x].r = r;node[x].setv = -1; node[x].flip = 0;if (l == r) {int tmp;scanf("%d", &tmp);for (int i = 0; i < 3; i++) {node[x].sum[i][tmp] = 1;node[x].sum[i][!tmp] = 0;}node[x].num = tmp;return;}int mid = (l + r) / 2;build(l, mid, lson(x));build(mid + 1, r, rson(x));pushup(x);}void add(int l, int r, int v, int x = 0) {if (node[x].l >= l && node[x].r <= r) {if (v == 2) node[x].gao2();else node[x].gao1(v);return;}int mid = (node[x].l + node[x].r) / 2;pushdown(x);if (l <= mid) add(l, r, v, lson(x));if (r > mid) add(l, r, v, rson(x));pushup(x);}Node query(int l, int r, int x = 0) {if (node[x].l >= l && node[x].r <= r)return node[x];int mid = (node[x].l + node[x].r) / 2;pushdown(x);Node ans;if (l <= mid && r > mid) ans = merge(query(l, r, lson(x)), query(l, r, rson(x)));else if (l <= mid) ans = query(l, r, lson(x));else if (r > mid) ans = query(l, r, rson(x));pushup(x);return ans;}int main() {scanf("%d", &t);while (t--) {scanf("%d%d", &n, &m);build(0, n - 1);int op, a, b;while (m--) {scanf("%d%d%d", &op, &a, &b);if (op <= 2) add(a, b, op);else if (op == 3) printf("%d\n", query(a, b).num);else if (op == 4) printf("%d\n", query(a, b).sum[2][1]);}}return 0;}
HDU 3397 sequence operation (line segment tree)