Hdu3911 Black And White (merge of line tree segments), hdu3911white
Question: There are two operations for a sequence consisting of 0 and 1. One is to flip the number of given intervals (0-> 1, 1-> 0 ), the other is to query the maximum length of a substring consisting of 1 in a given interval. Focus on Interval merging and latency marking.
# Include <iostream> # include <cstdio> # include <cstring> # include <cstdlib> # include <algorithm> # include <queue> # include <set> # include <map> # include <vector> # include <cmath> # define INF 0x3fffffffusing namespace std; const int N = 100010; struct Node {int l, r, lsum0, rsum0, msum0, lsum1, rsum1, msum1; int flag; // 0 does not need to be flipped, 1 use int Mid () {return (l + r)/2 ;}} tree [4 * N]; int a [N]; // merge left and right subtree void pushUp (int rt) {int ll = tree [rt * 2]. r-tree [r T * 2]. l + 1; int rl = tree [rt * 2 + 1]. r-tree [rt * 2 + 1]. l + 1; // The maximum number of consecutive tree numbers starting from left [rt]. lsum1 = tree [rt * 2]. lsum1; // if it is equal to the length of the Left subtree, the maximum if (tree [rt * 2] on the left of the right subtree is added. lsum1 = ll) {tree [rt]. lsum1 + = tree [rt * 2 + 1]. lsum1;} // Similarly, the maximum number of consecutive trees from right to 1 [rt]. rsum1 = tree [rt * 2 + 1]. rsum1; if (tree [rt * 2 + 1]. rsum1 = rl) {tree [rt]. rsum1 + = tree [rt * 2]. rsum1;} // The maximum substring in this interval is either in the middle, left or right, so the maximum substring is the maximum value in three cases. Tree [rt]. msum1 = max (tree [rt * 2]. msum1, tree [rt * 2 + 1]. msum1), tree [rt * 2]. rsum1 + tree [rt * 2 + 1]. lsum1); tree [rt]. lsum0 = tree [rt * 2]. lsum0; if (tree [rt * 2]. lsum0 = ll) {tree [rt]. lsum0 + = tree [rt * 2 + 1]. lsum0;} tree [rt]. rsum0 = tree [rt * 2 + 1]. rsum0; if (tree [rt * 2 + 1]. rsum0 = rl) {tree [rt]. rsum0 + = tree [rt * 2]. rsum0;} tree [rt]. msum0 = max (tree [rt * 2]. msum0, tree [rt * 2 + 1]. msum0), tree [rt * 2]. rsum0 + tree [rt * 2 + 1]. lsum0);} // switch void Swap (int rt) {swap (tree [rt]. lsum0, tree [rt]. lsum1); swap (tree [rt]. rsum0, tree [rt]. rsum1); swap (tree [rt]. msum0, tree [rt]. msum1);} // Update (lazy) void pushDown (int rt) {if (tree [rt]. flag = 1) {tree [rt * 2]. flag ^ = 1; tree [rt * 2 + 1]. flag ^ = 1; tree [rt]. flag = 0; Swap (rt * 2); Swap (rt * 2 + 1);} void build (int rt, int l, int r) {tree [rt]. l = l; tree [rt]. r = r; tree [rt]. flag = 0; // initialize each leaf node if (l = r) {if (a [l] = 0) {tree [rt]. lsum0 = t Ree [rt]. rsum0 = tree [rt]. msum0 = 1; tree [rt]. lsum1 = tree [rt]. rsum1 = tree [rt]. msum1 = 0;} else if (a [l] = 1) {tree [rt]. lsum0 = tree [rt]. rsum0 = tree [rt]. msum0 = 0; tree [rt]. lsum1 = tree [rt]. rsum1 = tree [rt]. msum1 = 1;} return;} int mid = (l + r)/2; build (2 * rt, l, mid); build (2 * rt + 1, mid + 1, r); pushUp (rt);} void update (int rt, int l, int r) {if (tree [rt]. l = l & tree [rt]. r = r) {tree [rt]. flag ^ = 1; Swap (rt); return;} // update subtree pushDown (Rt); if (r <= tree [rt]. mid () {update (2 * rt, l, r);} else if (l> tree [rt]. mid () {update (2 * rt + 1, l, r);} else {update (2 * rt, l, tree [rt]. mid (); update (2 * rt + 1, tree [rt]. mid () + 1, r);} // merge and update pushUp (rt);} int query (int rt, int l, int r) {if (tree [rt]. l = l & tree [rt]. r = r) {return tree [rt]. msum1 ;}pushdown (rt); int ans; if (r <= tree [rt]. mid () {ans = query (rt * 2, l, r);} else if (l> tree [rt]. mid () {ans = query (2 * rt + 1, l, r) ;} Else {int lr = query (2 * rt, l, tree [rt]. mid (); int rr = query (2 * rt + 1, tree [rt]. mid () + 1, r); int a = tree [rt * 2]. rsum1; if (a> tree [rt * 2]. r-l + 1) a = tree [rt * 2]. r-l + 1; int B = tree [rt * 2 + 1]. lsum1; if (B> r-tree [rt * 2 + 1]. l + 1) B = r-tree [rt * 2 + 1]. l + 1; ans = max (lr, rr), a + B);} pushUp (rt); return ans;} int main () {// freopen ("d: \ Test.txt", "r", stdin); int n; while (scanf ("% d", & n )! = EOF) {for (int I = 1; I <= n; I ++) scanf ("% d", & a [I]); build (1,1, n); int m; scanf ("% d", & m); while (m --) {int op, l, r; scanf ("% d", & op, & l, & r); if (op = 0) {cout <query (1, l, r) <endl;} else if (op = 1) {update (1, l, r) ;}} return 0 ;}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.