[Original question]
1858: [scoi2010] sequential operation time limit: 10 sec memory limit: 64 MB
Submit: 1031 solved: 529
[Submit] [Status] Descriptionlxhgww recently received a 01 sequence Containing N numbers, which are either 0 or 1. Now there are five conversion and query operations for this sequence: 0 a B converts all the numbers in the [a, B] range to 0 1 a B and [, b] all the numbers in the range are converted to 1 2 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 0 3 a B. Ask [a, B] How many 1 4 a B in total and 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? The first row of input data includes 2 numbers, N and M, indicating the sequence length and number of operations. The second row includes n numbers, indicating the initial state of the sequence, 3 numbers per row, op, A, B, (0 <= op <= A <= B <n) indicates that for the range [, b] perform operations labeled as op = "" <= "" DIV = "" style = "font-family: Arial, verdana, Helvetica, sans-serif; "> output outputs one row for each query operation, including one number, indicating the corresponding answer sample input10 10.
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
Sample output5
2
6
5
Hint
For 30% of data, 1 <= n, m <= 1000
For 100% of data, 1 <= n, m <= 100000
Source
Day2
[Analysis] It is really a complicated line segment tree question. I have never written about dyeing or other issues before, but I still found a method for finding the maximum number of consecutive segments in YY. In the online segment tree, you still need to record the numbers at the left and right endpoints of the interval. Later, the more complex I want, the longer I want to record the maximum number of consecutive left (and right) endpoints if they are 1 (and 0. Because in L ~ R from L ~ M and M + 1 ~ During r transfer, the maximum number of consecutive 1 values may be the result of merging the continuous 1 values of the left and right endpoints of the Left endpoints.
In addition, we need to record the maximum number of consecutive 0, because we need to reverse the range.
Dig a hole firstIf you are free, try again later.DetailsWrite the algorithm.
[Code]
#include<cstdio>#include<algorithm>#define N 100005#define LL a[L].r-a[L].l+1#define RR a[R].r-a[R].l+1#define PP a[P].r-a[P].l+1#define mid ((a[k].l+a[k].r)>>1)using namespace std;struct Tree{ int l,r,lnum,rnum,l1,r1,l0,r0,cover,num,max0,max1;}a[N*3];int data[N],x,y,opt,temp,n,i,Q;inline void up(int k){ int L=k<<1,R=k<<1|1; a[k].lnum=a[L].lnum;a[k].rnum=a[R].rnum; a[k].l1=a[L].l1;if (a[L].l1==LL) a[k].l1+=a[R].l1; a[k].r1=a[R].r1;if (a[R].r1==RR) a[k].r1+=a[L].r1; a[k].l0=a[L].l0;if (a[L].l0==LL) a[k].l0+=a[R].l0; a[k].r0=a[R].r0;if (a[R].r0==RR) a[k].r0+=a[L].r0; a[k].num=a[L].num+a[R].num; a[k].max1=max(a[L].max1,a[R].max1); if (a[L].rnum&a[R].lnum) a[k].max1=max(a[k].max1,a[L].r1+a[R].l1); a[k].max0=max(a[L].max0,a[R].max0); if ((!a[L].rnum)&(!a[R].lnum)) a[k].max0=max(a[k].max0,a[L].r0+a[R].l0);}inline void build(int k,int l,int r){ a[k].l=l;a[k].r=r; if (l==r) { a[k].lnum=a[k].rnum=a[k].l1=a[k].r1=a[k].num=a[k].max1=data[l]; a[k].l0=a[k].r0=a[k].max0=data[l]^1;return; } build(k<<1,l,mid); build(k<<1|1,mid+1,r); up(k);}inline void update(int P,int add){ if (add==1) { a[P].l1=a[P].r1=a[P].num=a[P].max1=PP; a[P].l0=a[P].r0=a[P].max0=0; a[P].lnum=a[P].rnum=1; } if (add==-1) { a[P].l1=a[P].r1=a[P].num=a[P].max1=a[P].lnum=a[P].rnum=0; a[P].l0=a[P].r0=a[P].max0=PP; } if (add==2) { swap(a[P].l0,a[P].l1);swap(a[P].r0,a[P].r1);swap(a[P].max0,a[P].max1); a[P].lnum^=1;a[P].rnum^=1; a[P].num=PP-a[P].num; }}inline void down(int k,int P){ update(P,temp=a[k].cover); if (temp&1) a[P].cover=temp; if (temp==2) { if (a[P].cover&1) a[P].cover=-a[P].cover; else a[P].cover=2-a[P].cover; }}void work(int k){ if (x<=a[k].l&&a[k].r<=y) { update(k,opt); if (!a[k].cover) a[k].cover=opt; else a[k].cover=(opt&1)?opt:((a[k].cover==2)?0:-a[k].cover); return; } down(k,k<<1);down(k,k<<1|1);a[k].cover=0; if (x<=mid) work(k<<1); if (y>mid) work(k<<1|1); up(k);}int ask(int k){ if (x<=a[k].l&&a[k].r<=y) return (opt==3)?a[k].num:a[k].max1; down(k,k<<1);down(k,k<<1|1);a[k].cover=0; int Mid=(a[k].l+a[k].r)>>1; if (opt==3) return (((x<=Mid)?ask(k<<1):0)+((y>Mid)?ask(k<<1|1):0)); int Max=0; if (x<=Mid) Max=max(Max,ask(k<<1)); if (y>Mid) Max=max(Max,ask(k<<1|1)); if (x<=Mid&&y>Mid) Max=max(Max,min(a[k<<1].r1,Mid-x+1)+min(a[k<<1|1].l1,y-Mid)); return Max;}inline int c(int k) {return (!k)?-1:k;}#define BUF_SIZE 100000#define OUT_SIZE 100000 bool IOerror=0; inline char nc(){ static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; if (p1==pend){ p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); }return *p1++; } inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';} inline void read(int &x){ bool sign=0; char ch=nc(); x=0; for (;blank(ch);ch=nc()); if (IOerror)return; if (ch=='-')sign=1,ch=nc(); for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0'; if (sign)x=-x; }int main(){ read(n);read(Q); for (i=1;i<=n;i++) read(data[i]); build(1,1,n); while (Q--) { read(opt);read(x);x++;read(y);y++; if (opt<3) opt=c(opt),work(1); else printf("%d\n",ask(1)); } return 0;}