hdu 3911 Black And White

Black And White

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3561    Accepted Submission(s): 1062


Problem Description
There are a bunch of stones on the beach; Stone color is white or black. Little Sheep has a magic brush, she can change the color of a continuous stone, black to white, white to black. Little Sheep like black very much, so she want to know the longest period of consecutive black stones in a range [i, j].
 
Input
  There are multiple cases, the first line of each case is an integer n(1<= n <= 10^5), followed by n integer 1 or 0(1 indicates black stone and 0 indicates white stone), then is an integer M(1<=M<=10^5) followed by M operations formatted as x i j(x = 0 or 1) , x=1 means change the color of stones in range[i,j], and x=0 means ask the longest period of consecutive black stones in range[i,j]
 
Output
When x=0 output a number means the longest length of black stones in range [i,j].
 
Sample Input
4
1 0 1 0
5
0 1 4
1 2 3
0 1 4
1 3 3
0 4 4
 
Sample Output
1
2
0
 
Source
 
  1 /**
  2 题意:两种操作
  3 0 l ,r 查找区间[ L , R ]里最长的连续1的数目。
  4 1 l ,r 更新区间[ L , R ]里的数字。0变成1,  1变成0
  5 
  6 思路:
  7 由于连续1的存在,我们需要保存lnum, rnum.  lmaxn, rmaxn maxn;
  8 加上1操作,我们还要有个延迟标记才行。
  9 bool  setFlag;
 10 
 11 如果就设置这些参数。在更新的时候,
 12 我们必须要找到一段连续相等数字的区间,对它进行延迟标记。
 13 i f ( f[n].maxn == f[n].len || f[n].maxn == 0 )
 14 
 15  这样的话,我们有可能更新到叶子节点。这样的时间就多了。
 16  其实,我们最期望的就是一旦找到区间[ L ,R ]的时候,就进行延迟
 17  标记,然后返回。
 18 
 19  由此,我们还要加上统计0个数的数据。
 20  Zlmaxn,Zrmaxn,Zmaxn;
 21  1的操作本质上也是 0  和 1的转化,所以交换它们的值就可以了。
 22 
 23  同时,我们需要注意,对于setFlag ,只有奇数次的时候才标记为ture;
 24 
 25 **/
 26 
 27 #include<iostream>
 28 #include<stdio.h>
 29 #include<cstring>
 30 #include<cstdlib>
 31 using namespace std;
 32 
 33 struct node
 34 {
 35     int l,r,len;
 36     int lnum,rnum;
 37     int lmaxn,rmaxn,maxn;
 38     int Zlmaxn,Zrmaxn,Zmaxn;
 39     bool setFlag;
 40 }f[100002*4];
 41 int date;
 42 
 43 void up(int n)
 44 {
 45     f[n].lnum = f[n*2].lnum;
 46     f[n].rnum = f[n*2+1].rnum;
 47 
 48     f[n].lmaxn = ( f[n*2].lmaxn==f[n*2].len && f[n*2].rnum==f[n*2+1].lnum ) ?
 49                      f[n*2].lmaxn+f[n*2+1].lmaxn:f[n*2].lmaxn;
 50     f[n].rmaxn = ( f[n*2+1].rmaxn == f[n*2+1].len && f[n*2].rnum == f[n*2+1].lnum) ?
 51                      f[n*2+1].rmaxn+f[n*2].rmaxn : f[n*2+1].rmaxn;
 52     f[n].maxn = max(f[n*2].maxn,f[n*2+1].maxn);
 53     if(f[n*2].rnum == 1 && f[n*2+1].lnum == 1)
 54         f[n].maxn = max(f[n].maxn,f[n*2].rmaxn+f[n*2+1].lmaxn);
 55 
 56     f[n].Zlmaxn = ( f[n*2].Zlmaxn==f[n*2].len && f[n*2].rnum==f[n*2+1].lnum ) ?
 57                      f[n*2].Zlmaxn+f[n*2+1].Zlmaxn:f[n*2].Zlmaxn;
 58     f[n].Zrmaxn = ( f[n*2+1].Zrmaxn == f[n*2+1].len && f[n*2].rnum == f[n*2+1].lnum) ?
 59                      f[n*2+1].Zrmaxn+f[n*2].Zrmaxn : f[n*2+1].Zrmaxn;
 60     f[n].Zmaxn = max(f[n*2].Zmaxn,f[n*2+1].Zmaxn);
 61     if(f[n*2].rnum == 0 && f[n*2+1].lnum == 0)
 62         f[n].Zmaxn = max(f[n].Zmaxn,f[n*2].Zrmaxn+f[n*2+1].Zlmaxn);
 63 }
 64 void build(int l,int r,int n)
 65 {
 66     int mid=(l+r)/2;
 67     f[n].l = l;
 68     f[n].r = r;
 69     f[n].len = f[n].r-f[n].l+1;
 70     f[n].setFlag = false;
 71     f[n].lnum=f[n].rnum=0;
 72     f[n].lmaxn=f[n].rmaxn=f[n].maxn=0;
 73     f[n].Zlmaxn=f[n].Zrmaxn=f[n].Zmaxn=0;
 74     if(l==r)
 75     {
 76         scanf("%d",&date);
 77         f[n].lnum=f[n].rnum=date;
 78         f[n].lmaxn=f[n].rmaxn=f[n].maxn=date;
 79         f[n].Zlmaxn=f[n].Zrmaxn=f[n].Zmaxn=(date^1);
 80         return;
 81     }
 82     build(l,mid,n*2);
 83     build(mid+1,r,n*2+1);
 84     up(n);
 85 }
 86 
 87 void down(int n)
 88 {
 89     f[n*2].setFlag = f[n*2].setFlag^1;
 90     /**传递的是奇数次,偶数次就抵消了,不需要向下更新**/
 91     swap(f[n*2].lmaxn,f[n*2].Zlmaxn);
 92     swap(f[n*2].rmaxn,f[n*2].Zrmaxn);
 93     swap(f[n*2].maxn,f[n*2].Zmaxn);
 94     f[n*2].lnum = (f[n*2].lnum^1);
 95     f[n*2].rnum = (f[n*2].rnum^1);
 96 
 97     f[n*2+1].setFlag = f[n*2+1].setFlag^1;
 98     /**传递的是奇数次,偶数次就抵消了,不需要向下更新**/
 99     swap(f[n*2+1].lmaxn,f[n*2+1].Zlmaxn);
100     swap(f[n*2+1].rmaxn,f[n*2+1].Zrmaxn);
101     swap(f[n*2+1].maxn,f[n*2+1].Zmaxn);
102     f[n*2+1].lnum=(f[n*2+1].lnum^1);
103     f[n*2+1].rnum=(f[n*2+1].rnum^1);
104 
105     f[n].setFlag = false;
106 }
107 void update(int l,int r,int n)
108 {
109     int mid=(f[n].l + f[n].r)/2;
110     if(f[n].l == l && f[n].r == r)
111     {
112         f[n].setFlag = (f[n].setFlag^1);
113         /**传递的是奇数次,偶数次就抵消了,不需要向下更新**/
114         f[n].lnum=(f[n].lnum^1);
115         f[n].rnum=(f[n].rnum^1);
116         swap(f[n].lmaxn,f[n].Zlmaxn);
117         swap(f[n].rmaxn,f[n].Zrmaxn);
118         swap(f[n].maxn,f[n].Zmaxn);
119         return ;
120     }
121     if(f[n].setFlag==true) down(n);
122     if(mid>=r) update(l,r,n*2);
123     else if(mid<l) update(l,r,n*2+1);
124     else
125     {
126         update(l,mid,n*2);
127         update(mid+1,r,n*2+1);
128     }
129     up(n);
130 }
131 
132 int query(int l,int r,int n)
133 {
134     int mid=(f[n].l + f[n].r)/2;
135     if(f[n].l == l && f[n].r==r)
136     {
137          return f[n].maxn;
138     }
139     if(f[n].setFlag==true) down(n);
140     if(mid>=r) return query(l,r,n*2);
141     else if(mid<l) return query(l,r,n*2+1);
142     else
143     {
144         int lmaxn = query(l,mid,n*2);
145         int rmaxn = query(mid+1,r,n*2+1);
146         int maxn = max(lmaxn,rmaxn);
147         if(f[n*2].rnum==1 && f[n*2+1].lnum ==1)
148             maxn = max(  maxn,min(mid-l+1,f[n*2].rmaxn)+min(r-mid,f[n*2+1].lmaxn)  );
149         return maxn;
150     }
151 }
152 
153 int main()
154 {
155     int n,m,l,r,size1;
156     while(scanf("%d",&n)>0)
157     {
158         build(1,n,1);
159         scanf("%d",&m);
160         while(m--)
161         {
162             scanf("%d%d%d",&size1,&l,&r);
163             if(size1==1)
164                 update(l,r,1);
165             else if(size1==0)
166                 printf("%d\n",query(l,r,1));
167         }
168     }
169     return 0;
170 }
原文地址:https://www.cnblogs.com/tom987690183/p/3057900.html