二次联通门 : 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. SQL高级教程

    一.top子句 top子句用于规定要返回的记录的数目 并非所有数据库系统都支持top子句 # sqlserver SELECT TOP number|percent column_name(s) FR ...

  2. Jmeter之分布式测试/压测

    Jmeter做分布式测试的原因: 测试机器的配置低,对服务器进行压测时,造成不了压力. jmeter并发10000后,测试机就已经卡顿了,而且测试结果有大量失败(忽略了jmeter自身问题=.=||| ...

  3. 从C++到Qt(舍弃IDE或qmake、cmake等工具的束缚,尝试通过几个例子)

    Qt 是 C++ 的库,Qt 在 ansi C++ 的基础上进行了一点扩展. 但国内似乎比较浮躁,学Qt的很多连基本的C++如何编译似乎都不太清楚.本文舍弃IDE或qmake.cmake等工具的束缚, ...

  4. Mysql union和union all用法

    1: 什么时候用union和union all ?    我们经常会碰到这样的应用,两个表的数据按照一定的查询条件查询出来以后,需要将结果合并到一起显示出来,这个时候 就需要用到union和union ...

  5. Spring Cloud Alibaba学习笔记(6) - Sentinel使用总结

    使用Sentinel API Sentinel主要有三个核心Api: SphU:定义资源,让资源收到监控,保护资源 SphU 包含了 try-catch 风格的 API.用这种方式,当资源发生了限流之 ...

  6. .net core的startup中配置读取

    public class Startup { public Startup(IHostingEnvironment env) { Configuration = new ConfigurationBu ...

  7. element-ui上传一张图片后隐藏上传按钮

    来自:https://github.com/ElemeFE/element/issues/3367#issuecomment-376402380 侵删 el-upload里面绑定一个占位class: ...

  8. Vue.js 教程 -- 实例讲解

    一. Vue.js是什么 Vue.js是一套构建用户界面(view)的MVVM框架.Vue.js的核心库只关注视图层,并且非常容易学习,非常容易与其他库或已有的项目整合. 1.1 Vue.js的目的 ...

  9. Eclipse上安装websphere

    Eclipse上安装websphere 参考:https://blog.csdn.net/qq_26264237/article/details/90107508 安装websphere插件 WebS ...

  10. Feign报错'xx.FeignClientSpecification', defined in null, could not be registered.

    解决: 在application.yml中配置: spring: main: allow-bean-definition-overriding: true 参考:https://blog.csdn.n ...