[Topic description] lxhgww recently received a 01 sequence Containing N numbers. These numbers are either 0 or 1, there are five transformation operations and inquiry operations for this sequence: 0 a B converts all the numbers in the [a, B] range to 01 a B and converts [, b] all the numbers in the range are converted to 12 a B, and all the numbers in the [a, B] range are reversed, that is, all 0 is changed to 1, change all 1 to 03 a B. Ask [a, B] The total number of 14 a B in the interval. Ask [, b] the maximum number of consecutive requests in the interval. For each query operation, lxhgww must provide an answer. Can you help a smart programmer? [Input] the first line of the input data includes 2 numbers, N and M, indicating the sequence length and number of operations. The second line includes n numbers, indicating the initial state of the sequence. The next m rows, 3 numbers per row, op, A, B, (0 <= op <= A <= B <n) indicates that for the range [, b] perform the op operation [Output] to output one row for each query operation, including one count, indicates the corresponding answer [Example input] 10 10 0 0 0 1 1 0 1 0 1 1 1 1 1 0 2 3 0 5 2 2 2 2 4 0 4 0 3 6 2 3 7 4 2 8 1 0 5 5 6 3 3 9 [sample output] 5 2 6 5 [data range] for 30% of data, 1 <= n, m <= 1000 for 100% of data, 1 <= n, m <= 100000
The same segment is invalid.
The topic is clear, but it involves various operations.
Tree [p]. Col is used to indicate the color of the partition. If Col = 1, all values are 1, Col = 0, and all values are 0, Col =-1, and all values are 1;
Tree [p]. maxl indicates the number of maxcompute 1 records starting from the left end of the region;
Tree [p]. maxr indicates the number of maxcompute 1 records starting from the right end of the region;
Tree [p]. sum indicates the total number of 1 in the region;
Tree [p]. Max indicates the maximum number of records in the region.
Software program injection.
Accode:
# Include <cstdio> # include <cstring> # include <cstdlib> # include <bitset> Using STD: min; Using STD: Max; Using STD: bitset; const char fi [] = "operation. in "; const char fo [] =" operation. out "; const int maxn = 100010; const int max = 0x3fffff00; const int min =-Max; struct segtree {int L, R, LC, RC, Col, maxl, maxr, max, sum ;}; segtree tree [maxn <2]; bitset <maxn> TMP; int n, m, TOT; void init_file () {freope N (FI, "r", stdin); freopen (FO, "W", stdout);} void Update (segtree * ths, segtree * LC, segtree * RC) {ths-> maxl = LC-> maxl; // only in the left-side navigation pane. If (LC-> Col = 1) ths-> maxl = max (Ths-> maxl, LC-> sum + RC-> maxl ); // if the value of the left sub-statement is 1, this condition exists. // The above two rows update maxl. Ths-> maxr = RC-> maxr; // only the right sub-region. If (RC-> Col = 1) ths-> maxr = max (Ths-> maxr, RC-> sum + LC-> maxr ); // if the right sub-statement is set to 1, this condition exists. // The above two rows update maxr. Ths-> max = max (LC-> MAX, RC-> MAX), LC-> maxr + RC-> maxl ); // update the value of max (three types of conditions: // only in the left-side Navigation Pane, and only in the right-side Navigation Pane and // cross the left-side Navigation Pane ). Ths-> sum = LC-> sum + RC-> sum; // update the value of sum (directly add the // sum value of the left and right subsums ). Ths-> Col =-1; if (LC-> Col =-1 | RC-> Col =-1) return; if (LC-> Col = RC-> col) ths-> Col = LC-> Col; // update the col value, ths is a single color when both the left and right sides are in a single color and the left and right sides are in the same color.} Void set (segtree * THS) {ths-> maxl = ths-> maxr = ths-> max = ths-> sum = ths-> r-THS-> L + 1; ths-> Col = 1;} // set the zone where ths is located to 1. Void reset (segtree * THS) {ths-> maxl = ths-> maxr = ths-> max = ths-> sum = ths-> Col = 0 ;} // set the zone where ths is located to 0. Void flip (segtree * THS) {ths-> maxl = ths-> maxr = ths-> max = ths-> sum = ths-> r-THS-> L + 1-THS-> sum; ths-> Col ^ = 1;} // flip the area where ths is located. Void build (int l, int R) {int now = ++ tot; tree [now]. L = L; tree [now]. R = r; If (L = r) {tree [now]. maxl = tree [now]. maxr = tree [now]. sum = tree [now]. max = tree [now]. col = TMP. test (l); return;} // condition. If (L <r) {int mid = (L + r)> 1; tree [now]. lc = tot + 1; build (L, mid); // first create the left sub-worker. Tree [now]. Rc = tot + 1; build (Mid + 1, R); // create the right sub-worker.} Update (tree + now, tree + tree [now]. LC, tree + tree [now]. Rc); // update the vertex information.} Void passdown (segtree * ths, segtree * LC, segtree * RC) {LC-> Col = RC-> Col = ths-> Col; // The colors of the left and right sides are not ths colors. LC-> maxl = LC-> maxr = LC-> max = LC-> sum = (Ths-> Col = 1 )? (LC-> r-LC-> L + 1): 0; // modify all the labels of the Left subvertex. RC-> maxl = RC-> maxr = RC-> max = RC-> sum = (Ths-> Col = 1 )? (RC-> r-RC-> L + 1): 0; // modify all the tags of the right sub-partition.} // Mark down (Ths should be a single color at this time ). Void set (INT now, int L, int R) {If (L> tree [now]. r | r <tree [now]. l | tree [now]. col = 1) return; // if it is not a normal condition or the color of the region is already 1, exit directly. If (L <= tree [now]. L & R> = tree [now]. r) {set (tree + now); return;} // if the area is completely overwritten, set it to 1 directly. If (tree [now]. col>-1) {passdown (tree + now, tree + tree [now]. LC, tree + tree [now]. RC); // If tree [now] is a single color, it is marked down. Tree [now]. Col =-1; // set tree [now] to multi-color.} Int mid = (tree [now]. L + tree [now]. r)> 1; if (L <= mid) Set (tree [now]. LC, L, R); // contains the left subscriber and returns the left subscriber. If (mid <r) Set (tree [now]. RC, L, R); // contains the right sub-region, which is the right sub-region. Update (tree + now, tree + tree [now]. LC, tree + tree [now]. RC);} void reset (INT now, int L, int R) {If (L> tree [now]. r | r <tree [now]. l | tree [now]. col = 0) return; // exit directly if it is not a normal condition or the color of the region is already 0. If (L <= tree [now]. L & R> = tree [now]. r) {reset (tree + now); return;} // if the region is completely overwritten, set it to 0. If (tree [now]. col>-1) {passdown (tree + now, tree + tree [now]. LC, tree + tree [now]. RC); // If tree [now] is a single color, it is marked down. Tree [now]. Col =-1; // set tree [now] to multi-color.} Int mid = (tree [now]. L + tree [now]. r)> 1; if (L <= mid) reset (tree [now]. LC, L, R); // contains the left subscriber and returns the left subscriber. If (mid <r) reset (tree [now]. RC, L, R); // contains the right subvertex, which is always the right subvertex. Update (tree + now, tree + tree [now]. LC, tree + tree [now]. RC);} void flip (INT now, int L, int R) {If (L> tree [now]. r | r <tree [now]. l) return; // exit if the condition is not correct. If (L <= tree [now]. L & R> = tree [now]. R & tree [now]. col>-1) {flip (tree + now); return;} // if the area is completely covered and the color is single, you can directly flip it over. If (tree [now]. col>-1) {passdown (tree + now, tree + tree [now]. LC, tree + tree [now]. RC); // If tree [now] is a single color, it is marked down. Tree [now]. Col =-1; // set tree [now] to multi-color.} Int mid = (tree [now]. L + tree [now]. r)> 1; if (L <= mid) Flip (tree [now]. LC, L, R); // If the left sub-statement is included, the left sub-statement is added. If (mid <r) Flip (tree [now]. RC, L, R); // if it contains the right subscriber, the right subscriber is always added. Update (tree + now, tree + tree [now]. LC, tree + tree [now]. RC);} segtree query (INT now, int L, int R) {If (L <= tree [now]. L & R> = tree [now]. r) return tree [now]; // if the region is completely overwritten, the information of the region is directly returned. If (tree [now]. col>-1) passdown (tree + now, tree + tree [now]. LC, tree + tree [now]. RC); // note the following points. Int mid = (tree [now]. L + tree [now]. r)> 1; if (r <= mid) return query (tree [now]. LC, L, R); // if it is completely overwritten by the left child, the information of the left child is returned. If (mid <L) return query (tree [now]. RC, L, R); // if it is completely overwritten by the right sub-Statement, the information of the right sub-statement is returned. Segtree ans, lc = query (tree [now]. LC, L, R), Rc = query (tree [now]. RC, L, R); // if the two subscripts are left or right, the two subscripts are used for searching. Update (& ANS, & lc, & rc); Return ans; // return result.} Void work () {scanf ("% d", & N, & M); For (INT I = 1; I <n + 1; ++ I) {int X; scanf ("% d", & X); If (x) TMP. set (I) ;}tot = 0; build (1, N); For (; m; -- m) {int op, L, R; scanf ("% d", & OP, & L, & R); If (L> r) STD: swap (L, R ); // exclude the illegal token. + + L; ++ R; // starts with the minus mark in the topic data. In this case, LR indicates the auto-increment of 1. Switch (OP) {Case 0: reset (1, L, R); break; // set [L, R] to 0. Case 1: Set (1, L, R); break; // set [L, R] to 1. Case 2: Flip (1, L, R); break; // roll over [L, R. Case 3: printf ("% d \ n", query (1, L, R). Sum); // query the sum of 1 of rows [L, R. Break; Case 4: printf ("% d \ n", query (1, L, R ). max); // query the maximum number of records in the range [L, R. Break ;}} int main () {init_file (); Work (); exit (0 );}
The second operation:
#include <cstdio>#include <cstdlib>#include <string>#include <algorithm>#define max(a, b) ((a) > (b) ? (a) : (b))const char fi[] = "operation.in";const char fo[] = "operation.out";const int maxN = 100010;const int MAX = 0x3f3f3f3f;const int MIN = ~MAX;struct SegTree{int L, R, lc, rc, col, cnt, maxL, maxR, Max;};SegTree tr[maxN << 1];int a[maxN], n, m, tot;inline void update(SegTree &ths, const SegTree &lc, const SegTree &rc){ ths.col = (lc.col == rc.col) ? lc.col : -1; ths.cnt = lc.cnt + rc.cnt; ths.maxL = lc.maxL; ths.maxR = rc.maxR; if (lc.col == 1) ths.maxL = max(ths.maxL, lc.cnt + rc.maxL); if (rc.col == 1) ths.maxR = max(ths.maxR, lc.maxR + rc.cnt); ths.Max = max(max(lc.Max, rc.Max), lc.maxR + rc.maxL); return;}inline void push_down(int &p){ tr[tr[p].lc].col = tr[tr[p].rc].col = tr[p].col; tr[tr[p].lc].cnt = tr[tr[p].lc].maxL = tr[tr[p].lc].maxR = tr[tr[p].lc].Max = tr[p].col ? (tr[tr[p].lc].R + 1 - tr[tr[p].lc].L) : 0; tr[tr[p].rc].cnt = tr[tr[p].rc].maxL = tr[tr[p].rc].maxR = tr[tr[p].rc].Max = tr[p].col ? (tr[tr[p].rc].R + 1 - tr[tr[p].rc].L) : 0; return;}void Build(int L, int R){ int Now = ++tot; tr[Now].L = L; tr[Now].R = R; if (L == R) { tr[Now].col = tr[Now].cnt = tr[Now].maxL = tr[Now].maxR = tr[Now].Max = a[L]; return; } int Mid = (L + R) >> 1; tr[Now].lc = tot + 1; Build(L, Mid); tr[Now].rc = tot + 1; Build(Mid + 1, R); update(tr[Now], tr[tr[Now].lc], tr[tr[Now].rc]); return;}void Reset(int p, int L, int R){ if (L <= tr[p].L && R >= tr[p].R) { tr[p].col = tr[p].cnt = tr[p].maxL = tr[p].maxR = tr[p].Max = 0; return; } if (tr[p].col != -1) push_down(p); int Mid = (tr[p].L + tr[p].R) >> 1; if (L <= Mid) Reset(tr[p].lc, L, R); // if (Mid < R) Reset(tr[p].rc, L, R); // update(tr[p], tr[tr[p].lc], tr[tr[p].rc]); return;}void Set(int p, int L, int R){ if (L <= tr[p].L && R >= tr[p].R) { tr[p].col = 1; tr[p].cnt = tr[p].maxL = tr[p].maxR = tr[p].Max = tr[p].R - tr[p].L + 1; return; } if (tr[p].col != -1) push_down(p); int Mid = (tr[p].L + tr[p].R) >> 1; if (L <= Mid) Set(tr[p].lc, L, R); // if (Mid < R) Set(tr[p].rc, L, R); // update(tr[p], tr[tr[p].lc], tr[tr[p].rc]); return;}void Flip(int p, int L, int R){ if (L <= tr[p].L && R >= tr[p].R && tr[p].col == 0) {Set(p, L, R); return;} if (L <= tr[p].L && R >= tr[p].R && tr[p].col == 1) {Reset(p, L, R); return;} if (tr[p].col != -1) push_down(p); int Mid = (tr[p].L + tr[p].R) >> 1; if (L <= Mid) Flip(tr[p].lc, L, R); // if (Mid < R) Flip(tr[p].rc, L, R); // update(tr[p], tr[tr[p].lc], tr[tr[p].rc]); return;}SegTree Query(int p, int L, int R){ if (L <= tr[p].L && R >= tr[p].R) return tr[p]; if (tr[p].col != -1) push_down(p); int Mid = (tr[p].L + tr[p].R) >> 1; if (Mid < L) return Query(tr[p].rc, L, R); if (R <= Mid) return Query(tr[p].lc, L, R); SegTree ans, lc = Query(tr[p].lc, L, R), rc = Query(tr[p].rc, L, R); update(ans, lc, rc); return ans;}inline int getint(){ int res = 0; char tmp; while (!isdigit(tmp = getchar())); do res = (res << 3) + (res << 1) + tmp - '0'; while (isdigit(tmp = getchar())); return res;}int main(){ freopen("operation.in", "r", stdin); freopen("operation.out", "w", stdout); n = getint(); m = getint(); for (int i = 0; i < n; ++i) a[i] = getint(); Build(0, n - 1); for (int L, R; m; --m) { switch (getint()) { case 0: L = getint(); R = getint(); Reset(1, L, R); break; case 1: L = getint(); R = getint(); Set(1, L, R); break; case 2: L = getint(); R = getint(); Flip(1, L, R); break; case 3: L = getint(); R = getint(); printf("%d\n", Query(1, L, R).cnt); break; case 4: L = getint(); R = getint(); printf("%d\n", Query(1, L, R).Max); break; } } return 0;}