题目大意:n个排成一列石头,其中有黑有白(1表示黑,0表示白),有两种操作:

(1)x=1,对相应区间的石头颜色取反。

(2)x=0,求相应区间内的最长连续的黑石石头的数目。

View Code
  1 #include <stdio.h>
  2 #define lson l,m,rt<<1
  3 #define rson m+1,r,rt<<1|1
  4 #define maxn 100000
  5 struct node
  6 {
  7     int llen1,llen0,rlen1,rlen0,maxlen1,maxlen0,col;
  8 }setree[maxn<<2];
  9 int max(int a,int b)
 10 {
 11     return a>b?a:b;
 12 }
 13 int min(int a,int b)
 14 {
 15     return a<b?a:b;
 16 }
 17 void pushup(int rt,int len)
 18 {
 19     setree[rt].llen1=setree[rt<<1].llen1;
 20     if(setree[rt<<1].llen1==len-len/2)
 21     setree[rt].llen1+=setree[rt<<1|1].llen1;
 22     
 23     setree[rt].rlen1=setree[rt<<1|1].rlen1;
 24     if(setree[rt<<1|1].rlen1==len/2)
 25     setree[rt].rlen1+=setree[rt<<1].rlen1;
 26     
 27     setree[rt].maxlen1=max(setree[rt<<1].rlen1+setree[rt<<1|1].llen1,max(setree[rt<<1].maxlen1,setree[rt<<1|1].maxlen1));
 28 
 29     setree[rt].llen0=setree[rt<<1].llen0;
 30     if(setree[rt<<1].llen0==len-len/2)
 31     setree[rt].llen0+=setree[rt<<1|1].llen0;
 32     
 33     setree[rt].rlen0=setree[rt<<1|1].rlen0;
 34     if(setree[rt<<1|1].rlen0==len/2)
 35     setree[rt].rlen0+=setree[rt<<1].rlen0;
 36     
 37     setree[rt].maxlen0=max(setree[rt<<1].rlen0+setree[rt<<1|1].llen0,max(setree[rt<<1].maxlen0,setree[rt<<1|1].maxlen0));
 38 }
 39 void pushdown(int rt)
 40 {
 41     if(setree[rt].col==2){
 42         int t;
 43         
 44         if(setree[rt<<1].col==2)
 45         setree[rt<<1].col=-1;
 46         else
 47         setree[rt<<1].col=2;
 48         
 49         t=setree[rt<<1].llen1;
 50         setree[rt<<1].llen1=setree[rt<<1].llen0;
 51         setree[rt<<1].llen0=t;
 52             
 53         t=setree[rt<<1].rlen1;
 54         setree[rt<<1].rlen1=setree[rt<<1].rlen0;
 55         setree[rt<<1].rlen0=t;
 56         
 57         t=setree[rt<<1].maxlen1;
 58         setree[rt<<1].maxlen1=setree[rt<<1].maxlen0;
 59         setree[rt<<1].maxlen0=t;
 60         
 61         if(setree[rt<<1|1].col==2)
 62         setree[rt<<1|1].col=-1;
 63         else
 64         setree[rt<<1|1].col=2;
 65         
 66         t=setree[rt<<1|1].llen1;
 67         setree[rt<<1|1].llen1=setree[rt<<1|1].llen0;
 68         setree[rt<<1|1].llen0=t;
 69             
 70         t=setree[rt<<1|1].rlen1;
 71         setree[rt<<1|1].rlen1=setree[rt<<1|1].rlen0;
 72         setree[rt<<1|1].rlen0=t;
 73         
 74         t=setree[rt<<1|1].maxlen1;
 75         setree[rt<<1|1].maxlen1=setree[rt<<1|1].maxlen0;
 76         setree[rt<<1|1].maxlen0=t;
 77         
 78         setree[rt].col=-1;
 79     }
 80 }
 81 void build(int l,int r,int rt)
 82 {
 83     if(l==r){
 84         scanf("%d",&setree[rt].col);
 85         setree[rt].llen1=setree[rt].rlen1=setree[rt].maxlen1=setree[rt].col?1:0;
 86         setree[rt].llen0=setree[rt].rlen0=setree[rt].maxlen0=setree[rt].col?0:1;
 87         return;
 88     }
 89     setree[rt].col=-1;
 90     int m=(l+r)>>1;
 91     build(lson);
 92     build(rson);
 93     pushup(rt,r-l+1);
 94 }
 95 void update(int l,int r,int rt,int L,int R)
 96 {
 97     int t;
 98     if(L<=l&&r<=R){
 99         if(setree[rt].col==2)
100         setree[rt].col=-1;
101         else
102         setree[rt].col=2;
103             t=setree[rt].llen1;
104             setree[rt].llen1=setree[rt].llen0;
105             setree[rt].llen0=t;
106             
107             t=setree[rt].rlen1;
108             setree[rt].rlen1=setree[rt].rlen0;
109             setree[rt].rlen0=t;
110             
111             t=setree[rt].maxlen1;
112             setree[rt].maxlen1=setree[rt].maxlen0;
113             setree[rt].maxlen0=t;
114             return;
115     }
116     pushdown(rt);
117     int m=(l+r)>>1;
118     if(L<=m)
119     update(lson,L,R);
120     if(R>m)
121     update(rson,L,R);
122     pushup(rt,r-l+1);
123 }
124 int query(int l,int r,int rt,int L,int R)
125 {
126     if(L<=l&&r<=R)
127     return setree[rt].maxlen1;
128     pushdown(rt);
129     int m=(l+r)>>1;
130     if(R<=m)
131     return query(lson,L,R);
132     else if(L>m)
133     return query(rson,L,R);
134     else{
135     int temp=max(query(lson,L,m),query(rson,m+1,R));
136     temp=max(min(m-L+1,setree[rt<<1].rlen1)+min(R-m,setree[rt<<1|1].llen1),temp);
137     return temp;
138     }
139 }
140 int main()
141 {
142     int n;
143     while(~scanf("%d",&n)){
144         build(1,n,1);
145         int op;
146         scanf("%d",&op);
147         while(op--){
148             int a,b,c;
149             scanf("%d%d%d",&a,&b,&c);
150             if(a==1)
151             update(1,n,1,b,c);
152             else
153             printf("%d\n",query(1,n,1,b,c));
154         }
155     }
156     return 0;
157 }