Question:
A series with the length of n (n <= 100000) is given, followed by five operations:
Insert operation:
0 a B: change the number of all [a, B] ranges to 0.
1 a B: change the number of all [a, B] ranges to 1.
2 a B returns the number of all [a, B] intervals to different values or a bit (0-side 1, 1, 0)
Output operation:
3 A B Outputs the number of 1 in the range [a, B]
4 A B Outputs the longest continuous 1 string in the range [a, B]
Solution:
The solution should be relatively simple. However, my solution is a bit orz. Each node information is:
There are so many PREB, Prew, sufb, sufw, mxb, mxw, sumb, sumw, and XOR.
The other few do not need to be said. sumb records the number of 1 in this interval, and XOR is the lazy sign (we didn't have this before, and we decided to wa it ). Then write it... But fortunately, push_up is not wrong...
Follow-up:
The simple solution is to maintain only one cov. Cov = 1/0, indicating that the range is all 1 or all 0, cov =-1 indicates that there are multiple values. Orz ....
/* Pro: 0sol: Date: */# include <iostream> # include <cstdio> # include <algorithm> # include <cstring> # include <cmath> # include <queue> # include <set> # include <vector> # define maxn 100010 # define ls RT <1 # define Rs RT <1 | 1 # define havem int M = (L + r)> 1 # define lson L, M, RT <1 # define rson m + 1, R, RT <1 | 1 using namespace STD; int PREB [maxn <2], sufb [maxn <2], Prew [maxn <2], sufw [maxn <2], Mxb [maxn <2], mxw [maxn <2]; int sumb [maxn <2], sumw [maxn <2], XOR [maxn <2]; int N, t, q, TMP, op, a, B; inline int max (int A, int B, int C) {return (A> B )? (A> C )? A: C): (B> C )? B: C);} void push_up (INT RT, int m) {sumb [RT] = sumb [ls] + sumb [RS]; sumw [RT] = sumw [ls] + sumw [RS]; PREB [RT] = PREB [ls]; if (PREB [ls] = m-(M> 1) PREB [RT] + = PREB [RS]; Prew [RT] = Prew [ls]; if (Prew [ls] = m-(M> 1) Prew [RT] + = Prew [RS]; sufb [RT] = sufb [RS]; if (sufb [RS] = (M> 1) sufb [RT] + = sufb [ls]; sufw [RT] = sufw [RS]; if (sufw [RS] = (M> 1) sufw [RT] + = sufw [ls]; mxb [RT] = max (mxb [ls], mxb [RS], PREB [RS] + sufb [ls]); mxw [RT] = max (mxw [ls], mxw [RS], prew [RS] + sufw [ls]);} void exc (int rt) {swap (PREB [RT], Prew [RT]); swap (sufb [RT], sufw [RT]); swap (sumb [RT], sumw [RT]); swap (mxb [RT], mxw [RT]);} void push_dn (int rt, int m) {If (XOR [RT]) {// exclusive or lazy, XOR [ls] ^ = 1; XOR [RS] ^ = 1; exc (LS); EXC (RS); XOR [RT] = 0;} If (sumb [RT] = m) {PREB [ls] = sufb [ls] = mxb [ls] = sumb [ls] = m-(M> 1 ); PREB [RS] = sufb [RS] = mxb [RS] = sumb [RS] = (M> 1 ); prew [ls] = sufw [ls] = mxw [ls] = sumw [ls] = 0; prew [RS] = sufw [RS] = mxw [RS] = sumw [RS] = 0;} else if (sumw [RT] = m) {PREB [ls] = sufb [ls] = mxb [ls] = sumb [ls] = 0; PREB [RS] = sufb [RS] = mxb [RS] = sumb [RS] = 0; prew [ls] = sufw [ls] = mxw [ls] = sumw [ls] = m-(M> 1 ); prew [RS] = sufw [RS] = mxw [RS] = sumw [RS] = (M> 1) ;}} void build (int l, int R, int RT) {XOR [RT] = 0; If (L = r) {scanf ("% d", & TMP); If (TMP) {PREB [RT] = sufb [RT] = mxb [RT] = sumb [RT] = 1; prew [RT] = sufw [RT] = mxw [RT] = sumw [RT] = 0 ;} else {PREB [RT] = sufb [RT] = mxb [RT] = sumb [RT] = 0; prew [RT] = sufw [RT] = mxw [RT] = sumw [RT] = 1;} return;} havem; build (lson); Build (rson ); push_up (RT, R-l + 1);} void Update (int l, int R, int op, int L, int R, int RT) {If (L <= L & R <= r) {If (OP = 0) {PREB [RT] = sufb [RT] = mxb [RT] = sumb [RT] = 0; prew [RT] = sufw [RT] = mxw [RT] = sumw [RT] = r-L + 1; return;} else if (OP = 1) {PREB [RT] = sufb [RT] = mxb [RT] = sumb [RT] = r-L + 1; prew [RT] = sufw [RT] = mxw [RT] = sumw [RT] = 0; return;} exc (RT); XOR [RT] ^ = 1; return;} havem; push_dn (RT, R-l + 1); If (L <= m) Update (L, R, op, lson); If (r> m) update (L, R, op, rson); push_up (RT, R-l + 1);} int query3 (int l, int R, int L, int R, int RT) {// 3 All 1's; 4 longest 1's if (L <= L & R <= r) {return sumb [RT];} havem; push_dn (RT, R-l + 1); int ret = 0; If (L <= m) RET + = query3 (L, R, lson ); if (r> m) RET + = query3 (L, R, rson); return ret;} int query4 (int l, int R, int L, int R, int RT) {// 3 All 1's; 4 longest 1's if (L <= L & R <= r) {return mxb [RT];} havem; push_dn (RT, R-l + 1); If (r <= m) return query4 (L, R, lson); If (L> m) return query4 (L, r, rson); int ret = max (query4 (L, R, lson), query4 (L, R, rson); ret = max (Ret, min (m-L + 1, sufb [ls]) + min (r-m, PREB [RS]); return ret;} int main () {scanf ("% d", & T); While (t --) {scanf ("% d", & N, & Q); Build (0, n-1, 1); // For (INT I = 0; I <q; I ++) {scanf ("% d", & OP, &, & B); If (OP = 0) {update (A, B, op, 0, n-1, 1 ); // The duration is changed to 0} else if (OP = 1) {update (A, B, op, 0, N ); // The duration is changed to 1} else if (OP = 2) {update (A, B, op, 0, n-1, 1 ); // period swapping} else if (OP = 3) {printf ("% d \ n", query3 (a, B, 0, N )); // All 1's in [a, B]} else {printf ("% d \ n", query4 (a, B, 0, N-1,1 )); // longest 1's in [a, B] }}return 0 ;}
# Include <cstdio> using namespace STD; # define maxn 100010 # define lson L, M, RT <1 # define rson m + 1, R, RT <1 | 1 # define ls RT <1 # define Rs RT <1 | 1 # define havem int M = (L + r)> 1int N, Q, a, B, T; // you must first declare that CoV is not a lazy sign, otherwise it will not appear in the push_up int cov [maxn <2], RI, max_len, cur_len; void push_up (int rt) {If (COV [ls] = cov [RS]) // cov can be-1 cov [RT] = cov [ls]; else cov [RT] =-1;} void build (int l, int R, int RT) {If (L = r) {scanf ("% d ", & cov [RT]); return;} havem; build (lson); Build (rson); push_up (RT);} void push_dn (int rt) {If (COV [RT]> = 0) {cov [ls] = cov [RS] = cov [RT]; cov [RT] =-1 ;}} void Update (int l, int R, int Val, int L, int R, int RT) {If (COV [RT] = Val) return; if (L <= L & R <= r) {cov [RT] = val; return;} push_dn (RT); havem; If (L <= m) update (L, R, Val, lson); If (r> m) Update (L, R, Val, rson); push_up (RT);} void update_xor (INT l, int R, int L, int R, int RT) {If (L <= L & R <= R & cov [RT]> = 0) {cov [RT] ^ = 1; return;} push_dn (RT); havem; If (L <= m) update_xor (L, R, lson ); if (r> m) update_xor (L, R, rson); push_up (RT);} int query (int l, int R, int L, int R, int RT) {If (L <= L & R <= r) {If (COV [RT] = 0) {return 0;} If (COV [RT] = 1) {return r-L + 1 ;}} havem; push_dn (RT); If (r <= m) return query (L, R, lson); If (L> m) return query (L, R, rson); Return query (L, R, lson) + query (L, R, rson);} void queryl (int l, int R, int L, int R, int RT) {If (COV [RT] = 0) return; if (L <= L & R <= R & cov [RT] = 1) {If (L = RI + 1) // if this interval is followed by the previous interval cur_len + = r-L + 1; else cur_len = r-L + 1; if (cur_len> max_len) max_len = cur_len; ri = r; return;} push_dn (RT); havem; If (r <= m) queryl (L, R, lson); else if (L> m) queryl (L, R, rson); else // here is M and M + 1, here I wa for a long time, this keeps up with the above L = RI + 1 related to queryl (L, m, lson), queryl (m + 1, R, rson);} int main () {scanf ("% d", & T); int op, A, B; while (t --) {scanf ("% d", & N, & Q); Build (1, n, 1); While (Q --) {scanf ("% d", & OP, & A, & B); A ++, B ++; Switch (OP) {Case 0: update (a, B, 0, 1, n, 1); break; Case 1: Update (A, B, 1, 1, n, 1); break; Case 2: update_xor (, b, 1, n, 1); break; Case 3: printf ("% d \ n", query (A, B, 1, n, 1); break; case 4: max_len = cur_len = 0; rI = 0; queryl (A, B, 1, n, 1); printf ("% d \ n ", max_len );}}}}