二次联通门 : BZOJ 1858: [Scoi2010]序列操作
/*
BZOJ 1858: [Scoi2010]序列操作
已经...
没有什么好怕的的了... 16K的代码... 调个MMP啊... */
#include <cstdio> void read (int &now)
{
now = ;
register char word = getchar ();
while (word < '' || word > '')
word = getchar ();
while (word >= '' && word <= '')
{
now = now * + word - '';
word = getchar ();
}
} inline int max (int a, int b)
{
return a > b ? a : b;
} inline int min (int a, int b)
{
return a < b ? a : b;
} inline int swap (int &a, int &b)
{
register int now = a;
a = b;
b = now;
} struct Segment_Tree_Data
{
Segment_Tree_Data *Left, *Right; int Mid;
int key; int l, r; int Nor_Flandre;
bool Rev_Flandre; int Zero_Prefix_, Zero_Suffix_;
int Zero_Series_Count;
int Zero_Count; int One_Prefix_, One_Suffix_;
int One_Series_Count;
int One_Count; Segment_Tree_Data ()
{
Left = Right = NULL;
Nor_Flandre = ;
Rev_Flandre = ;
} inline void Clear_One ()
{
One_Count = ;
One_Prefix_ = One_Suffix_ = ;
One_Series_Count = ;
} inline void Clear_Zero ()
{
Zero_Count = ;
Zero_Prefix_ = Zero_Suffix_ = ;
Zero_Series_Count = ;
} inline void Cover_One ()
{
One_Count = r - l + ;
One_Prefix_ = One_Count;
One_Suffix_ = One_Count;
One_Series_Count = One_Count;
} inline void Cover_Zero ()
{
Zero_Count = r - l + ;
Zero_Prefix_ = Zero_Count;
Zero_Suffix_ = Zero_Count;
Zero_Series_Count = Zero_Count;
} inline void Swap_Zero_and_One ()
{
swap (Zero_Count, One_Count);
swap (Zero_Prefix_, One_Prefix_);
swap (Zero_Suffix_, One_Suffix_);
swap (Zero_Series_Count, One_Series_Count);
}
}; Segment_Tree_Data *Root; int Answer; struct Answer_Type
{
int size;
int _Prefix, _Suffix;
int Count;
int Answer;
}; class Segment_Tree_Type
{
private : inline void Up (Segment_Tree_Data *&now)
{
if (now->l == now->r)
return ;/*
now->Zero_Prefix_ = max (now->Left->Zero_Prefix_, now- >Left->Zero_Count + now->Right->Zero_Prefix_);
now->Zero_Suffix_ = max (now->Right->Zero_Suffix_, now- >Right->Zero_Count + now->Left->Zero_Suffix_);
now->Zero_Series_Count = max (max (now->Left- >Zero_Series_Count, now->Right->Zero_Series_Count), now->Right- >Zero_Prefix_ + now->Left->Zero_Suffix_); now->One_Prefix_ = max (now->Left->One_Prefix_, now->Left- >One_Count + now->Right->One_Prefix_);
now->One_Suffix_ = max (now->Right->One_Suffix_, now- >Right->One_Count + now->Left->One_Suffix_);
now->One_Series_Count = max (max (now->Left- >One_Series_Count, now->Right->One_Series_Count), now->Right- >One_Prefix_ + now->Left->One_Suffix_);
*/
now->One_Prefix_ = now->Left->One_Count == now ->Left->r - now->Left->l + ? now->Left->One_Count : now->Left- >One_Prefix_;
now->One_Suffix_ = now->Right->One_Count == now->Right->r - now->Right->l + ? now->Right->One_Count : now->Right ->One_Suffix_; now->Zero_Prefix_ = now->Left->Zero_Count == now->Left->r - now->Left->l + ? now->Left->Zero_Count : now->Left- >Zero_Prefix_;
now->Zero_Suffix_ = now->Right->Zero_Count == now->Right->r - now->Right->l + ? now->Right->Zero_Count : now- >Right->Zero_Suffix_; now->One_Series_Count = max (max (now->Left- >One_Series_Count, now->Right->One_Series_Count), now->Left- >One_Suffix_ + now->Right->One_Prefix_);
now->Zero_Series_Count = max (max (now->Left- >Zero_Series_Count, now->Right->Zero_Series_Count), now->Left- >Zero_Suffix_ + now->Right->Zero_Prefix_); now->One_Count = now->Left->One_Count + now->Right- >One_Count;
now->Zero_Count = now->Left->Zero_Count + now->Right- >Zero_Count;
return ;
} inline void Down (Segment_Tree_Data *&now)
{
if (now->l == now->r)
return ;
if (now->Nor_Flandre)
{
if (now->Nor_Flandre == )
{/*
now->Left->One_Count = now->Left->r - now->Left->l + 1;
now->Right->One_Count = now->Right->r - now->Right ->l + 1; now->Left->One_Prefix_ = now->Left->One_Count;
now->Left->One_Suffix_ = now->Left->One_Count;
now->Right->One_Prefix_ = now->Right->One_Count;
now->Right->One_Suffix_ = now->Right->One_Count; now->Left->One_Series_Count = now->Left->One_Count;
now->Right->One_Series_Count = now->Right- >One_Count; now->Left->Nor_Flandre = 1;
now->Right->Nor_Flandre = 1;
*/
now->Left->Cover_One ();
now->Right->Cover_One ();
now->Left->Rev_Flandre = false;
now->Right->Rev_Flandre = false;
now->Left->Clear_Zero ();
now->Right->Clear_Zero (); now->Nor_Flandre = ;
}
else if (now->Nor_Flandre == )
{/*
now->Left->Zero_Count = now->Left->r - now->Left->l + 1;
now->Right->Zero_Count = now->Right->r - now- >Right->l + 1; now->Left->Zero_Prefix_ = now->Left->Zero_Count;
now->Left->Zero_Suffix_ = now->Left->Zero_Count;
now->Right->Zero_Prefix_ = now->Right->Zero_Count;
now->Right->Zero_Suffix_ = now->Right->Zero_Count; now->Left->Zero_Series_Count = now->Left- >Zero_Count;
now->Right->Zero_Series_Count = now->Right- >Zero_Count; now->Left->Nor_Flandre = 2;
now->Right->Nor_Flandre = 2;
*/
now->Left->Cover_Zero ();
now->Right->Cover_Zero ();
now->Left->Rev_Flandre = false;
now->Right->Rev_Flandre = false;
now->Left->Clear_One ();
now->Right->Clear_One (); now->Nor_Flandre = ;
}
}
if (now->Rev_Flandre)
{/*
swap (now->Left->One_Count, now->Left->Zero_Count);
swap (now->Left->One_Prefix_, now->Left->Zero_Count);
swap (now->Left->One_Series_Count, now->Left- >Zero_Series_Count);
swap (now->Left->One_Suffix_, now->Left->Zero_Suffix_); swap (now->Right->One_Count, now->Right->Zero_Count);
swap (now->Right->One_Prefix_, now->Right->Zero_Count);
swap (now->Right->One_Series_Count, now->Right- >Zero_Series_Count);
swap (now->Right->One_Suffix_, now->Left- >Zero_Suffix_);
*/
now->Left->Swap_Zero_and_One ();
now->Right->Swap_Zero_and_One ();
now->Left->Rev_Flandre = true;
now->Right->Rev_Flandre = true; now->Rev_Flandre = false;
}
} public : void Build (Segment_Tree_Data *&now, int l, int r)
{
now = new Segment_Tree_Data;
now->l = l;
now->r = r;
if (l == r)
{
read (now->key);
if (now->key)
{
now->One_Count = ;
now->One_Prefix_ = ;
now->One_Suffix_ = ;
now->One_Series_Count = ;
now->Clear_Zero ();
return ;
}
else
{
now->Zero_Count = ;
now->Zero_Prefix_ = ;
now->Zero_Suffix_ = ;
now->Zero_Series_Count = ;
now->Clear_One ();
return ;
}
}
now->Mid = l + r >> ;
Build (now->Left, l, now->Mid);
Build (now->Right, now->Mid + , r);
Up (now);
} void Change_First (Segment_Tree_Data *&now, int l, int r)
{
if (l <= now->l && now->r <= r)
{/*
now->Zero_Count = now->r - now->l + 1;
now->Zero_Prefix_ = now->Zero_Count;
now->Zero_Suffix_ = now->Zero_Count;
now->Zero_Series_Count = now->Zero_Count;
*/
now->Cover_Zero ();
now->Clear_One ();
now->Nor_Flandre = ;
return ;
}
Down (now);
if (l <= now->Mid)
Change_First (now->Left, l, min (now->Mid, r));
if (r > now->Mid)
Change_First (now->Right, max (now->Mid + , l), r);
Up (now);
} void Change_Second (Segment_Tree_Data *&now, int l, int r)
{
if (l <= now->l && now->r <= r)
{
now->Cover_One ();
now->Clear_Zero (); now->Nor_Flandre = ;
return ;
}
Down (now);
if (l <= now->Mid)
Change_Second (now->Left, l, min (now->Mid, r));
if (r > now->Mid)
Change_Second (now->Right, max (now->Mid + , l), r);
Up (now);
} void Change_Third (Segment_Tree_Data *&now, int l, int r)
{
if (l <= now->l && now->r <= r)
{
now->Swap_Zero_and_One ();
now->Rev_Flandre = true;
return ;
}
Down (now);
if (l <= now->Mid)
Change_Third (now->Left, l, min (now->Mid, r));
if (r > now->Mid)
Change_Third (now->Right, max (now->Mid + , l), r);
Up (now);
} int Query_First (Segment_Tree_Data *&now, int l, int r)
{
if (l <= now->l && now->r <= r)
return now->One_Count;
Down (now);
register int res = ;
if (l <= now->Mid)
res += Query_First (now->Left, l, min (now->Mid, r));
if (r > now->Mid)
res += Query_First (now->Right, max (now->Mid + , l), r);
Up (now);
return res;
}
/*
Segment_Tree_Data *Query_Second (Segment_Tree_Data *&now, int l, int r)
{
if (l <= now->l && now->r <= r)
return now;
Down (now);
Up (now);
Segment_Tree_Data *res = new Segment_Tree_Data;
Segment_Tree_Data *now_1 = new Segment_Tree_Data, *now_2 = new Segment_Tree_Data;
bool flag_1 = false, flag_2 = false;
if (l <= now->Mid)
{
flag_1 = true;
now_1 = Query_Second (now->Left, l, min (now->Mid, r));
}
if (r > now->Mid)
{
flag_2 = true;
now_2 = Query_Second (now->Right, max (now->Mid + 1, l), r);
}
if (flag_1 && flag_2)
{
now_1 = Query_Second (now->Left, l, min (now->Mid, r));
now_2 = Query_Second (now->Right, max (now->Mid + 1, l), r);
res.One_Prefix_ = max (now_1.One_Prefix_, now_1.One_Count + now_2.One_Prefix_);
res.One_Suffix_ = max (now_2.One_Suffix_, now_2.One_Count + now_1.One_Suffix_);
res.One_Series_Count = max (max (now_1.One_Series_Count, now_2.One_Series_Count), now_1.One_Suffix_ + now_2.One_Prefix_);
return res; now_1 = Query_Second (now->Left, l, min (now->Mid, r));
now_2 = Query_Second (now->Right, max (now->Mid + 1, l), r);
res->One_Count = now_1->One_Count + now_2->One_Count;
res->One_Prefix_ = max (now_1->One_Prefix_, now_1- >One_Count + now_2->One_Prefix_);
res->One_Suffix_ = max (now_2->One_Suffix_, now_2- >One_Count + now_1->One_Suffix_);
res->One_Series_Count = max (max (now_1- >One_Series_Count, now_2->One_Series_Count), now_1->One_Suffix_ + now_2->One_Prefix_);
Answer = max (Answer, res->One_Series_Count);
Answer = max (Answer, res->One_Prefix_);
Answer = max (Answer, res->One_Suffix_);
return res;
}
if (flag_1)
{
Answer = max (Answer, now_1->One_Series_Count);
Answer = max (Answer, now_1->One_Prefix_);
Answer = max (Answer, now_1->One_Suffix_);
return now_1;
}
if (flag_2)
{
Answer = max (Answer, now_2- >One_Series_Count);
Answer = max (Answer, now_2- >One_Prefix_);
Answer = max (Answer, now_2- >One_Suffix_);
return now_2;
}
}*/ Answer_Type Query_ (Segment_Tree_Data *&now, int l, int r)
{
if (l <= now->l && now->r <= r)
return (Answer_Type)
{
now->r - now->l + ,
now->One_Prefix_,
now->One_Suffix_,
now->One_Count,
now->One_Series_Count
};
Down (now);
Up (now);
Answer_Type now_1, now_2;
register bool flag_1 = false, flag_2 = false;
if (l <= now->Mid)
{
flag_1 = true;
now_1 = Query_ (now->Left, l, min (now ->Mid, r));
}
if (r > now->Mid)
{
flag_2 = true;
now_2 = Query_ (now->Right, max (now- >Mid + , l), r);
}
if (flag_1 && flag_2)
{
Answer_Type res;
res.Count = now_1.Count + now_2.Count;
res._Prefix = now_1.size == now_1.Count ? now_1.Count : now_1._Prefix;
res._Suffix = now_2.size == now_2.Count ? now_2.Count : now_2._Suffix;
res.Answer = max (max (now_1.Answer, now_2.Answer), now_1._Suffix + now_2._Prefix);
return res;
}
return flag_1 ? now_1 : now_2;
}
}; Segment_Tree_Type Tree;
int N, M; int main (int argc, char *argv[])
{
read (N);
read (M);
Root = NULL;
Tree.Build (Root, , N);
int type, x, y;
for (; M--; )
{
read (type);
read (x);
x++;
read (y);
y++;
if (type == )
Tree.Change_First (Root, x, y);
else if (type == )
Tree.Change_Second (Root, x, y);
else if (type == )
Tree.Change_Third (Root, x, y);
else if (type == )
printf ("%d\n", Tree.Query_First (Root, x, y));
else
{
// Answer = -1;
// Tree.Query_Second (Root, x, y);
// printf ("%d\n", Answer);
Answer_Type res = Tree.Query_ (Root, x, y);
printf ("%d\n", max (max (res._Prefix, res._Suffix), res.Answer));
}
}
return ;
}