record the continuous segments of 0 and 1 respectively. It is not difficult to change the 01 value or think clearly.
# Include <stdio. h> # include <string. h> # include <algorithm> using namespace STD; # define lson L, M, RT <1 # define rson m + 1, R, RT <1 | 1 # define ls (RT <1) # define RS (RT <1 | 1) const int M = 100001; int N, D; int XOR [m <2]; int cover [m <2]; int LPA [m <2] [2], RPA [m <2] [2], MPA [m <2] [2], num [m <2] [2]; int L, R, OP; int max (int A, int B) {return A> B? A: B;} int min (int A, int B) {return a <B? A: B;} void swap (Int & A, Int & B) {int temp = A; A = B; B = temp;} void or (INT RT) {If (cover [RT]! =-1) {cover [RT] ^ = 1;} else {XOR [RT] ^ = 1 ;}} void swap (int rt) {swap (LPA [RT] [0], LPA [RT] [1]); swap (RPA [RT] [0], RPA [RT] [1]); swap (MPA [RT] [0], MPA [RT] [1]); swap (Num [RT] [0], num [RT] [1]);} void pushup (int m, int Len, int RT) {for (INT I = 0; I <2; I ++) {LPA [RT] [I] = LPA [ls] [I]; RPA [RT] [I] = RPA [RS] [I]; if (LPA [RT] [I] = len-(LEN> 1) LPA [RT] [I] + = LPA [RS] [I]; if (RPA [RT] [I] = (LEN> 1) RPA [RT] [I] + = RPA [ls] [I]; MPA [RT] [I] = RPA [ls] [I] + LPA [RS] [I]; MPA [RT] [I] = max (MPA [RT] [I], max (MPA [ls] [I], MPA [RS] [I]); MPA [RT] [I] = max (MPA [RT] [I], max (LPA [RT] [I], RPA [RT] [I]); num [RT] [I] = num [ls] [I] + num [RS] [I];} If (cover [ls]! =-1 & cover [ls] = cover [RS]) cover [RT] = cover [ls]; else cover [RT] =-1 ;} void Pushdown (int m, int Len, int RT) {If (cover [RT]! =-1) {d = cover [RT]; LPA [ls] [d] = RPA [ls] [d] = MPa [ls] [d] = num [ls] [d] = len-(LEN> 1); LPA [ls] [! D] = RPA [ls] [! D] = MPa [ls] [! D] = num [ls] [! D] = 0; cover [ls] = cover [RS] = D; XOR [ls] = XOR [RS] = 0; LPA [RS] [d] = RPA [RS] [d] = MPa [RS] [d] = num [RS] [d] = (LEN> 1 ); LPA [RS] [! D] = RPA [RS] [! D] = MPa [RS] [! D] = num [RS] [! D] = 0;} else if (XOR [RT]) {or (LS); swap (LS); or (RS); swap (RS );} cover [RT] =-1; XOR [RT] = 0;} void build (int l, int R, int RT) {XOR [RT] = 0; if (L = r) {scanf ("% d", & D); cover [RT] = D; LPA [RT] [d] = RPA [RT] [d] = MPa [RT] [d] = num [RT] [d] = 1; LPA [RT] [! D] = RPA [RT] [! D] = MPa [RT] [! D] = num [RT] [! D] = 0;} else {int M = (L + r)> 1; build (lson); Build (rson); pushup (M, R-l + 1, RT) ;}} void Update (int l, int R, int RT) {If (L <= L & R <= r) {If (OP <= 1) {XOR [RT] = 0; cover [RT] = op; LPA [RT] [op] = RPA [RT] [op] = MPa [RT] [op] = num [RT] [op] = r-L + 1; LPA [RT] [! OP] = RPA [RT] [! OP] = MPa [RT] [! OP] = num [RT] [! OP] = 0 ;}else {swap (RT); or (RT) ;}} else {int M = (L + r) >> 1; Pushdown (m, r-l + 1, RT); If (L <= m) Update (lson); If (M <r) Update (rson); pushup (m, r-l + 1, RT) ;}} int query (int l, int R, int RT) {If (L <= L & R <= r) {If (OP = 3) return num [RT] [1]; else return MPa [RT] [1];} else {int M = (L + r)> 1; Pushdown (M, R-l + 1, RT); If (OP = 3) {int ans = 0; If (L <= m) ans = query (lson); If (M <r) ans + = query (rson); Return ans;} else {int ans = min (RPA [ls] [1], m-l + 1) + min (LPA [RS] [1], r-m); If (L <= m) ans = max (ANS, query (lson); If (M <r) ans = max (ANS, query (rson); Return ans ;}} int main () {int m; int CAS; scanf ("% d", & CAS); While (CAS --) {scanf ("% d", & N, & M); Build (0, n-1, 1); While (M --) {scanf ("% d", & OP, & L, & R); If (OP> = 3) printf ("% d \ n", query (0, n-1, 1); else Update (0, n-1, 1) ;}} return 0 ;}
interval modification, interval exclusive or, interval merging, and typical line segment tree questions