二次联通门 : codevs 2421 序列操作
/* 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊... */ #include <cstdio> void read (int &now) { now = 0; register char word = getchar (); while (word < ‘0‘ || word > ‘9‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; 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 = 0; Rev_Flandre = 0; } inline void Clear_One () { One_Count = 0; One_Prefix_ = One_Suffix_ = 0; One_Series_Count = 0; } inline void Clear_Zero () { Zero_Count = 0; Zero_Prefix_ = Zero_Suffix_ = 0; Zero_Series_Count = 0; } inline void Cover_One () { One_Count = r - l + 1; One_Prefix_ = One_Count; One_Suffix_ = One_Count; One_Series_Count = One_Count; } inline void Cover_Zero () { Zero_Count = r - l + 1; 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 + 1 ? now->Left->One_Count : now->Left- >One_Prefix_; now->One_Suffix_ = now->Right->One_Count == now->Right->r - now->Right->l + 1 ? now->Right->One_Count : now->Right ->One_Suffix_; now->Zero_Prefix_ = now->Left->Zero_Count == now->Left->r - now->Left->l + 1 ? now->Left->Zero_Count : now->Left- >Zero_Prefix_; now->Zero_Suffix_ = now->Right->Zero_Count == now->Right->r - now->Right->l + 1 ? 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 == 1) {/* 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 = 0; } else if (now->Nor_Flandre == 2) {/* 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 = 0; } } 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 = 1; now->One_Prefix_ = 1; now->One_Suffix_ = 1; now->One_Series_Count = 1; now->Clear_Zero (); return ; } else { now->Zero_Count = 1; now->Zero_Prefix_ = 1; now->Zero_Suffix_ = 1; now->Zero_Series_Count = 1; now->Clear_One (); return ; } } now->Mid = l + r >> 1; Build (now->Left, l, now->Mid); Build (now->Right, now->Mid + 1, 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 = 2; 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 + 1, 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 = 1; 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 + 1, 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 + 1, 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 = 0; 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 + 1, 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 + 1, 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 + 1, 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, 1, N); int type, x, y; for (; M--; ) { read (type); read (x); x++; read (y); y++; if (type == 0) Tree.Change_First (Root, x, y); else if (type == 1) Tree.Change_Second (Root, x, y); else if (type == 2) Tree.Change_Third (Root, x, y); else if (type == 3) 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 0; }
时间: 2024-11-05 19:28:04