[Cpp]/********************************** * ********* the subject is as follows: 0 a B converts all the numbers in the range [a, B] to 0 1 a B, and all the numbers in the range [a, B] to 1 2 a B, in B], there are 0 1 swaps, 0 changes, 1 changes, 0, 3 a B, and the number of 1 in the output range [a, B] is 4 a B. The output range is [, b] algorithm analysis of the number of longest consecutive 1: involves multiple operations on the Line Segment tree; two operations can be merged into the same write; interchange is the same or operation of the Line Segment tree; in the process of querying the maximum number of consecutive 1; maxl = [l, m]; maxl = [m + 1, r] the maximum number of consecutive 1; maxm = min (m-l + 1, rs of the left child) + min (r-m, ls of the right child); the result should be the maximum value among the three, that is, max (maxl, maxr, maxm). query operations are similar to pku3667 ;**************** * ******************************/# Include <iostream> # include <cstring> # include <cstdlib> # include <cstdio> # include <climits> # include <algorithm> using namespace std; # define L l, m, u <1 # define R m + 1, r, u <1 | 1 const int N = 100010; struct node {int l, r; int ls, ms, rs; // ls left longest continuous 1 count; ms: maximum continuous 1 count; rs: maximum continuous 1 count on the right; int flag; // 01 status int total; // total number of ranges 1} t [N * 3]; int len (int u) {return t [u]. r-t [u]. l + 1;} int mid (in T u) {return (t [u]. l + t [u]. r)> 1;} void PushUp (int u, int x) // update the information of the current node to the parent node {t [u]. ls = t [u]. ms = t [u]. rs = t [u]. total = x * (t [u]. r-t [u]. l + 1); t [u]. flag = x;} void build (int l, int r, int u) // build {t [u]. l = l; t [u]. r = r; t [u]. ls = t [u]. rs = t [u]. ms = t [u]. total = t [u]. flag = 0; if (l = r) return; int m = mid (u); build (L); build (R);} void PushUp (int u) // update the information of the current node to the parent node {t [u]. flag = (t [u <1]. flag = t [u <1 | 1]. flag? T [u <1]. flag:-1); // Update Status t [u]. ls = t [u <1]. ls + (t [u <1]. ls = len (u <1 ))? T [u <1 | 1]. ls: 0); // update the left t [u]. rs = t [u <1 | 1]. rs + (t [u <1 | 1]. rs = len (u <1 | 1 ))? T [u <1]. rs: 0); // update the right t [u]. ms = max (t [u <1]. rs + t [u <1 | 1]. ls, max (t [u <1]. ms, t [u <1 | 1]. ms); // update the overall t [u]. total = t [u <1]. total + t [u <1 | 1]. total; // total number of updates 1} void update (int l, int r, int u, int x) // update interval [l, r] 0, 1 status {if (t [u]. flag = x) return; if (t [u]. l = l & t [u]. r = r) {PushUp (u, x); return;} if (t [u]. flag> = 0) {PushUp (u <1, t [u]. flag); PushUp (u <1 | 1, t [u]. flag); t [u]. flag =-1;} int m = mid (u); if (r <= m) {update (l, r, u <1, x );} else if (l> m) {update (l, r, u <1 | 1, x);} else {update (L, x); update (R, x);} PushUp (u);} void swap (int l, int r, int u) // [l, r] 0, 1 switch {if (t [u]. l> = l & t [u]. r <= r & (t [u]. flag = 0 | t [u]. flag = 1) {int x = t [u]. flag ^ 1; PushUp (u, x); return;} if (t [u]. flag> = 0) {PushUp (u <1, t [u]. flag); PushUp (u <1 | 1, t [u]. flag);} int m = mid (u); if (r <= m) {swap (l, r, u <1);} else if (l> m) {swap (l, r, u <1 | 1) ;}else {swap (L); swap (R) ;}pushup (u );} int find1 (int l, int r, int u) // find the number of 1 in the range [l, r] {if (t [u]. l = l & t [u]. r = r) {return t [u]. total;} if (t [u]. flag> = 0) {PushUp (u <1, t [u]. flag); PushUp (u <1 | 1, t [u]. flag) ;}int m = mid (u); if (r <= m) {return find1 (l, r, u <1 );} else if (l> m) {return find1 (l, r, u <1 | 1);} else {return find1 (L) + find1 (R );}} int find2 (int l, int r, int u) // find the maximum number of consecutive 1 in the interval [l, r] {if (t [u]. l = l & t [u]. r = r) {return t [u]. ms;} if (t [u]. flag> = 0) {PushUp (u <1, t [u]. flag); PushUp (u <1 | 1, t [u]. flag) ;}int m = mid (u); if (r <= m) {return find2 (l, r, u <1 );} else if (l> m) {return find2 (l, r, u <1 | 1);} else {int maxl = find2 (L); // [l, m] the maximum number of consecutive 1 int maxr = find2 (R); // The maximum number of consecutive 1 int maxm = min (m-l + 1, t [u <1]. rs) + min (r-m, t [u <1 | 1]. ls); // min (m-l + 1, rs of the left child) + min (r-m, ls of the right child), return max (maxm, max (maxl, maxr) ;}} int main () {// freopen ("C: \ Users \ Administrator \ Desktop \ kd.txt", "r", stdin ); int t; scanf ("% d", & t); while (t --) {int n, m; scanf ("% d", & n, & m); build (0, n-1, 1); for (int I = 0; I <n; I ++) {int x; scanf ("% d ", & x); if (x) update (I, I, 1, x) ;}for (int I = 0; I <m; I ++) {int op, a, B; scanf ("% d", & op, & a, & B); if (op = 0 | op = 1) update (a, B, 1, op); else if (op = 2) swap (a, B, 1); else if (op = 3) printf ("% d \ n", find1 (a, B, 1); else if (op = 4) printf ("% d \ n", find2 (, b, 1) ;}} return 0 ;}