二次联通门 : 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. nodeJs+vue安装教程详解 相信

    相信很多朋友都在装node服务和安装vue的时候会遇到一些问题,下面为大家详细介绍node服务的安装以及vue的安装: 1.nodeJs官网下载版本(根据自己电脑的配置进行相应下载即可):默认安装路径 ...

  2. windows下mysql表名区分大小写

    windows下mysql默认是不区分大小写的,但是linux会区分大小写 如何让windows下mysql区分大小写呢? 修改 my.ini 里面的mysqld部分 #区分大小写 lower_cas ...

  3. Gogs + Drone 实现CI/CD(CI)

    本文通过docker-compose方式安装运行drone,先将drone的server和agent镜像拉取到本地,这样docker-compose脚本执行速度会快一点.当然,不是必须先拉取drone ...

  4. 读取经纬度坐标并存储为字典格式,即key为ID,value为轨迹点

    示例数据: #格式为txt文本 ID,L,B 001,116.5154,45.1154 001,116.5160,45.1153 ... 002,xxx,xxx ... 目标:建立轨迹数据结构,即di ...

  5. Java构建器(多个构造器参数)

    今天看netty权威指南,第一次听说构建器,百度了几个博客,但是并没有通俗易懂一点儿的,综合别人的博客,总结如下: 1. 构建器是什么? 当创建对象需要传入多个参数的时候我们通常会根据参数的数量写不同 ...

  6. 【MySQL】数据库(分库分表)中间件对比

    分区:对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm. 根据一定的规则把数据文件(MYD)和索引文件(MYI)进行了分割,分区后的表 ...

  7. Java 之 OutputStreamReader类

    OutputStreamReader类 1.概述 转换流 java.io.OutputStreamReader ,是Writer的子类,是从字符流到字节流的桥梁. 它使用指定的字符集将字符编码为字节. ...

  8. BHD钱包部署【生态池/合作池】

    前序 BHD网址:https://btchd.org/#wallet 注:我这里是centos7, 所以我选linuxPC 部署 解压与配置 tar -zxf bhd-v1.3.4.0-d909c0e ...

  9. 阿里云服务器(Ubuntu16.04 64位)的使用

    购买阿里云服务器 1.打开阿里云官方网站,账号登录,选择产品中的云服务器 ECS 2.根据自身需求,选择合适的阿里云服务器系统,(1)点击一键购买,(2)选择地域,(3)根据自身需求,选择系统,这里选 ...

  10. java - day015 - 手写双向链表, 异常(续), IO(输入输出)

    类的内存分配 加载到方法区 对象在堆内存 局部变量在栈内存 判断真实类型,在方法区加载的类 对象.getClass(); 类名.class; 手写双向链表 package day1501_手写双向链表 ...