二次联通门 : 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 ;
}

(WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作的更多相关文章

  1. bzoj 1858: [Scoi2010]序列操作

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...

  2. BZOJ 1858: [Scoi2010]序列操作( 线段树 )

    略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...

  3. bzoj 1858: [Scoi2010]序列操作【线段树】

    合并中间那块的时候没取max--WAWAWA 在线段树上维护一堆东西,分别是len区间长度,sm区间内1的个数,ll0区间从左开始最长连续0,ml0区间中间最长连续0,rl0区间从右开始最长连续0,l ...

  4. bzoj 1858: [Scoi2010]序列操作 || 洛谷 P2572

    记一下:线段树占空间是$2^{ceil(log2(n))+1}$ 这个就是一个线段树区间操作题,各种标记的设置.转移都很明确,只要熟悉这类题应该说是没有什么难度的. 由于对某区间set之后该区间原先待 ...

  5. 1858: [Scoi2010]序列操作

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 3397 Solved: 1624 [Submit][Statu ...

  6. bzoj1858[Scoi2010]序列操作 线段树

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 3079  Solved: 1475[Submit][Statu ...

  7. BZOJ_1858_[Scoi2010]序列操作_线段树

    BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...

  8. 【题解】Luogu P2572 [SCOI2010]序列操作

    原题传送门:P2572 [SCOI2010]序列操作 这题好弱智啊 裸的珂朵莉树 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 操作1:把区间内所有数推平成0,珂朵莉树基本操作 ...

  9. P2572 [SCOI2010]序列操作

    对自己 & \(RNG\) : 骄兵必败 \(lpl\)加油! P2572 [SCOI2010]序列操作 题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要 ...

随机推荐

  1. go context 源码分析

    WithCancel func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { c := newCancelCtx(pare ...

  2. Scratch(四)舞台区详解

    在Scratch里面,所有的表现结果都在“舞台区”呈现,前面我们学习的“石头剪刀布”游戏,也是在“舞台区”完成的. 舞台区是非常重要的区域,所以我们今天单独用一个章节来详细说说这个舞台. 既然是一个舞 ...

  3. create-react-app中的一些功能配置

    1. 根路径别名@ 1. npm run eject调出配置文件.找到webpack.config.js,搜索到,alias,在下面添加一行键值对'@':paths.appSrc, alias: { ...

  4. Angular Material 学习笔记 Chips

    依据 material guidelines, chips 可以用来做 filter https://material.io/design/components/chips.html#filter-c ...

  5. Spring中bean的管理

    Spring 中常见的容器 我们知道spring容器就是spring中bean的驻留场所.spring容器并不是只有一个.spring自带了多个容器实现,可以归为两种不同的类型:bean工厂和应用上下 ...

  6. javascript 之 Object.defineProperty

    语法: Object.definePropty(obj,prop,descriptor); 参数: obj:要在其上定义属性的属性 prop:要定义或修改的属性的名称 desriptor:将被定义或修 ...

  7. 常用NLog配置

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...

  8. md5 helper

    public static string ToMD5Hash(this string str) { if (string.IsNullOrEmpty(str)) return null; return ...

  9. LCD驱动的学习

    简介: LCD是基于液晶的. LCD(liquid crystal display)按驱动方式分类可以分为静态驱动,简单矩阵驱动,主动矩阵驱动.其中,简单矩阵又可以分为扭转向列型(TN)和超转向列型( ...

  10. scrapy框架介绍

    一,介绍 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等)的具有很强通用性 ...