(WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : 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]序列操作的更多相关文章
- bzoj 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...
- BZOJ 1858: [Scoi2010]序列操作( 线段树 )
略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...
- bzoj 1858: [Scoi2010]序列操作【线段树】
合并中间那块的时候没取max--WAWAWA 在线段树上维护一堆东西,分别是len区间长度,sm区间内1的个数,ll0区间从左开始最长连续0,ml0区间中间最长连续0,rl0区间从右开始最长连续0,l ...
- bzoj 1858: [Scoi2010]序列操作 || 洛谷 P2572
记一下:线段树占空间是$2^{ceil(log2(n))+1}$ 这个就是一个线段树区间操作题,各种标记的设置.转移都很明确,只要熟悉这类题应该说是没有什么难度的. 由于对某区间set之后该区间原先待 ...
- 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 3397 Solved: 1624 [Submit][Statu ...
- bzoj1858[Scoi2010]序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 3079 Solved: 1475[Submit][Statu ...
- BZOJ_1858_[Scoi2010]序列操作_线段树
BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...
- 【题解】Luogu P2572 [SCOI2010]序列操作
原题传送门:P2572 [SCOI2010]序列操作 这题好弱智啊 裸的珂朵莉树 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 操作1:把区间内所有数推平成0,珂朵莉树基本操作 ...
- P2572 [SCOI2010]序列操作
对自己 & \(RNG\) : 骄兵必败 \(lpl\)加油! P2572 [SCOI2010]序列操作 题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要 ...
随机推荐
- 开始Jupyter Notebooks
开始Jupyter Notebooks 安装Anaconda 因为不能有空格,所以没有选C:\Program Files 认识Jupyter Notebooks 修改 jupyter notebook ...
- git 修改注释
原文:https://www.jianshu.com/p/098d85a58bf1 修改最后一条注释: git commit --amend 如果已经推送到远程,强制push到远程仓库: git pu ...
- jmeter保存返回数据到csv
添加一个线程组,然后右键选择“正则表达式提取器” 配置正则表达式: 添加添加后置处理器beanshell postprocessor: 保存提取的数据: 代码: FileWriter fstream ...
- 在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字)
原文:在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.
- Java 面向对象_多态
多态图解 代码中体现多态性 父类名称 对象名 = new 子类名称(); or 接口名称 对象名 = new 实现类名称(); // 父类 public class Father { public v ...
- Nginx的启动、停止等命令
Windows下Nginx的启动.停止等命令 在Windows下使用Nginx,我们需要掌握一些基本的操作命令,比如:启动.停止Nginx服务,重新载入Nginx等,下面我就进行一些简单的介绍.1.启 ...
- JavaScript时钟效果
在JavaScript中,有一个内置对象Date,它重要的一个作用就是实现了时间的时刻更新,通过代码来创造一个实实在在的时间表. 代码例子: <!DOCTYPE html> <htm ...
- Java 之 缓冲流
一.缓冲流概述 缓冲流,也叫高效流,是对四个 FileXXX 流的增强,所有也有四个流,按照类型分类: 字节缓冲流:BufferedInputStream,BufferedOutputStream 字 ...
- ubuntu下使用JNI Java调用C++的例子
TestJNI.java public class TestJNI { static{ System.load("/home/buyizhiyou/workspace/JNI/src/lib ...
- Flutter——Switch组件(开关组件)
Switch组件常用的属性: 属性 描述 value 单选的值 onChanged 改变时触发 activeColor 选中的颜色.背景颜色 import 'package:flutter/mater ...