using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Linq;
class
Node
{
public
int
l1, r1, l0, r0;
public
int
min0, max0, min1, max1;
public
Node()
{
l1 = r1 = l0 = r0 = -1;
max1 = max0 =
int
.MinValue;
min1 = min0 =
int
.MaxValue;
}
}
class
LazyPropagationSegmentTree
{
public
static
int
MAX = 100001;
public
static
int
[] lazy =
new
int
[MAX];
public
static
Node[] seg =
new
Node[MAX];
public
static
Node MergeUtil(Node l, Node r)
{
Node x =
new
Node();
x.l0 = (l.l0 != -1) ? l.l0 : r.l0;
x.r0 = (r.r0 != -1) ? r.r0 : l.r0;
x.l1 = (l.l1 != -1) ? l.l1 : r.l1;
x.r1 = (r.r1 != -1) ? r.r1 : l.r1;
x.min0 = Math.Min(l.min0, r.min0);
if
(l.r0 != -1 && r.l0 != -1)
x.min0 = Math.Min(x.min0, r.l0 - l.r0);
x.min1 = Math.Min(l.min1, r.min1);
if
(l.r1 != -1 && r.l1 != -1)
x.min1 = Math.Min(x.min1, r.l1 - l.r1);
x.max0 = Math.Max(l.max0, r.max0);
if
(l.l0 != -1 && r.r0 != -1)
x.max0 = Math.Max(x.max0, r.r0 - l.l0);
x.max1 = Math.Max(l.max1, r.max1);
if
(l.l1 != -1 && r.r1 != -1)
x.max1 = Math.Max(x.max1, r.r1 - l.l1);
return
x;
}
public
static
Node UpdateUtil(Node x)
{
int
temp;
temp = x.l0; x.l0 = x.l1; x.l1 = temp;
temp = x.r0; x.r0 = x.r1; x.r1 = temp;
temp = x.min0; x.min0 = x.min1; x.min1 = temp;
temp = x.max0; x.max0 = x.max1; x.max1 = temp;
return
x;
}
public
static
void
Build(
int
qs,
int
qe,
int
ind,
int
[] arr)
{
if
(qs == qe) {
if
(arr[qs] == 1) {
seg[ind].l1 = seg[ind].r1 = qs;
}
else
{
seg[ind].l0 = seg[ind].r0 = qs;
}
lazy[ind] = 0;
return
;
}
int
mid = (qs + qe) >> 1;
Build(qs, mid, ind << 1, arr);
Build(mid + 1, qe, ind << 1 | 1, arr);
seg[ind] = MergeUtil(
seg[ind << 1],
seg[ind << 1 | 1]);
}
public
static
Node Query(
int
qs,
int
qe,
int
ns,
int
ne,
int
ind)
{
if
(lazy[ind] != 0) {
seg[ind] = UpdateUtil(seg[ind]);
if
(ns != ne) {
lazy[ind * 2] ^= lazy[ind];
lazy[ind * 2 + 1] ^= lazy[ind];
}
lazy[ind] = 0;
}
Node x =
new
Node();
if
(qs <= ns && qe >= ne)
return
seg[ind];
if
(ne < qs || ns > qe || ns > ne)
return
x;
int
mid = (ns + ne) >> 1;
Node l = Query(qs, qe, ns,
mid, ind << 1);
Node r = Query(qs, qe,
mid + 1, ne,
ind << 1 | 1);
x = MergeUtil(l, r);
return
x;
}
public
static
void
RangeUpdate(
int
us,
int
ue,
int
ns,
int
ne,
int
ind)
{
if
(lazy[ind] != 0) {
seg[ind] = UpdateUtil(seg[ind]);
if
(ns != ne) {
lazy[ind * 2] ^= lazy[ind];
lazy[ind * 2 + 1] ^= lazy[ind];
}
lazy[ind] = 0;
}
if
(ns > ne || ns > ue || ne < us)
return
;
if
(ns >= us && ne <= ue) {
seg[ind] = UpdateUtil(seg[ind]);
if
(ns != ne) {
lazy[ind * 2] ^= 1;
lazy[ind * 2 + 1] ^= 1;
}
return
;
}
int
mid = (ns + ne) >> 1;
RangeUpdate(us, ue, ns, mid, ind << 1);
RangeUpdate(us, ue, mid + 1, ne, ind << 1 | 1);
Node l = seg[ind << 1], r = seg[ind << 1 | 1];
seg[ind] = MergeUtil(l, r);
}
static
void
Main()
{
for
(
int
i = 0; i < 100001; i++){
seg[i] =
new
Node();
}
int
[] arr = { 1, 1, 0,
1, 0, 1,
0, 1, 0,
1, 0, 1,
1, 0 };
int
n = arr.Length;
Build(0, n - 1, 1, arr);
Node ans = Query(3, 7, 0, n - 1, 1);
Console.WriteLine(ans.min1);
ans = Query(2, 5, 0, n - 1, 1);
Console.WriteLine(ans.max1);
RangeUpdate(1, 4, 0, n - 1, 1);
ans = Query(3, 7, 0, n - 1, 1);
Console.WriteLine(ans.min0);
ans = Query(4, 9, 0, n - 1, 1);
Console.WriteLine(ans.max0);
}
}