bzoj 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作
Time Limit: 10 Sec Memory Limit: 64 MB
线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊处理一下。
Description
Input
Output
Sample Input
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
Sample Output
2
6
5
HINT
对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000
Source
#include<cstdio>
#define M 100010
inline int max(int a,int b){return a>b?a:b;}
struct tree{int l,r,s,lazy,sum,ml1,mr1,mm1,ml0,mr0,mm0;}tr[M*];
int a[M],n,m,x,y,v,op;
inline int read()
{
int tmp=;
char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<=''){tmp=tmp*+ch-'';ch=getchar();}
return tmp;
}
inline void pu(int p)
{
int p1=p<<,p2=p<<|;
tr[p].sum=tr[p1].sum+tr[p2].sum;
tr[p].mm1=tr[p1].mr1+tr[p2].ml1;
tr[p].mm0=tr[p1].mr0+tr[p2].ml0;
if(tr[p1].mr1==tr[p1].s) tr[p].ml1=tr[p1].mr1+tr[p2].ml1;
else tr[p].ml1=tr[p1].ml1;
if(tr[p1].mr0==tr[p1].s) tr[p].ml0=tr[p1].mr0+tr[p2].ml0;
else tr[p].ml0=tr[p1].ml0;
if(tr[p2].mr1==tr[p2].s) tr[p].mr1=tr[p2].mr1+tr[p1].mr1;
else tr[p].mr1=tr[p2].mr1;
if(tr[p2].mr0==tr[p2].s) tr[p].mr0=tr[p2].mr0+tr[p1].mr0;
else tr[p].mr0=tr[p2].mr0;
tr[p].mm1=max(tr[p].mm1,max(tr[p1].mm1,tr[p2].mm1));
tr[p].mm0=max(tr[p].mm0,max(tr[p1].mm0,tr[p2].mm0));
}
inline void change(int p)
{
int t1=tr[p].ml0,t2=tr[p].mr0,t3=tr[p].mm0;
tr[p].ml0=tr[p].ml1;
tr[p].ml1=t1;
tr[p].mr0=tr[p].mr1;
tr[p].mr1=t2;
tr[p].mm0=tr[p].mm1;
tr[p].mm1=t3;
}
inline void make(int l,int r,int p)
{
tr[p].l=l,tr[p].r=r,tr[p].s=tr[p].r-tr[p].l+,tr[p].lazy=-;
if(l==r)
{
tr[p].sum=a[l];
tr[p].ml1=tr[p].mm1=tr[p].mr1=a[l];
tr[p].ml0=tr[p].mm0=tr[p].mr0=a[l]^;
return;
}
int mid=(l+r)>>;
make(l,mid,p<<);
make(mid+,r,p<<|);
pu(p);
}
inline void pd(int p)
{
int lz=tr[p].lazy,p1=p<<,p2=p<<|;
if(lz==)
{
tr[p1].lazy=tr[p2].lazy=;
tr[p1].sum=;
tr[p2].sum=;
tr[p1].ml1=tr[p1].mr1=tr[p1].mm1=;
tr[p2].ml1=tr[p2].mr1=tr[p2].mm1=;
tr[p1].ml0=tr[p1].mr0=tr[p1].mm0=tr[p1].s;
tr[p2].ml0=tr[p2].mr0=tr[p2].mm0=tr[p2].s;
}
else if(lz==)
{
tr[p1].lazy=tr[p2].lazy=;
tr[p1].sum=tr[p1].s;
tr[p2].sum=tr[p2].s;
tr[p1].ml1=tr[p1].mr1=tr[p1].mm1=tr[p1].s;
tr[p2].ml1=tr[p2].mr1=tr[p2].mm1=tr[p2].s;
tr[p1].ml0=tr[p1].mr0=tr[p1].mm0=;
tr[p2].ml0=tr[p2].mr0=tr[p2].mm0=;
}
else if(lz==)
{
if(tr[p1].lazy==) tr[p1].lazy=;
else if(tr[p1].lazy==) tr[p1].lazy=;
else if(tr[p1].lazy==) tr[p1].lazy=-;
else tr[p1].lazy=;
if(tr[p2].lazy==) tr[p2].lazy=;
else if(tr[p2].lazy==) tr[p2].lazy=;
else if(tr[p2].lazy==) tr[p2].lazy=-;
else tr[p2].lazy=;
tr[p1].sum=tr[p1].s-tr[p1].sum;
tr[p2].sum=tr[p2].s-tr[p2].sum;
change(p1);change(p2);
}
tr[p].lazy=-;
}
inline int find1(int l,int r,int p)
{
pd(p);
if(tr[p].l==l&&tr[p].r==r) return tr[p].sum;
int mid=(tr[p].l+tr[p].r)>>;
if(mid>=r) return find1(l,r,p<<);
else if(mid<l) return find1(l,r,p<<|);
else return find1(l,mid,p<<)+find1(mid+,r,p<<|);
}
inline int findl(int l,int r,int p)
{
pd(p);
if(tr[p].ml1+l>r) return r-l+;
else return tr[p].ml1;
}
inline int findr(int l,int r,int p)
{
pd(p);
if(l+tr[p].mr1>r) return r-l+;
else return tr[p].mr1;
}
inline int find2(int l,int r,int p)
{
pd(p);
if(tr[p].l==l&&tr[p].r==r) return max(tr[p].ml1,max(tr[p].mm1,tr[p].mr1));
int mid=(tr[p].l+tr[p].r)>>;
if(mid>=r) return find2(l,r,p<<);
else if(mid<l) return find2(l,r,p<<|);
else return max(max(find2(l,mid,p<<),find2(mid+,r,p<<|)),findl(mid+,r,p<<|)+findr(l,mid,p<<));
}
inline void xg(int l,int r,int c,int p)
{
pd(p);
if(tr[p].l==l&&tr[p].r==r)
{
tr[p].lazy=c;
if(c==)
{
tr[p].ml1=tr[p].mr1=tr[p].mm1=;
tr[p].ml0=tr[p].mr0=tr[p].mm0=tr[p].s;
tr[p].sum=;
}
else if(c==)
{
tr[p].ml0=tr[p].mr0=tr[p].mm0=;
tr[p].ml1=tr[p].mr1=tr[p].mm1=tr[p].s;
tr[p].sum=tr[p].s;
}
else
{
tr[p].sum=tr[p].s-tr[p].sum;
change(p);
}
return;
}
int mid=(tr[p].l+tr[p].r)>>;
if(mid>=r) xg(l,r,c,p<<);
else if(mid<l) xg(l,r,c,p<<|);
else
{
xg(l,mid,c,p<<);
xg(mid+,r,c,p<<|);
}
pu(p);
}
int main()
{
n=read(),m=read();
for(int i=;i<=n;i++) a[i]=read();
make(,n,);
for(int i=;i<m;i++)
{
op=read();x=read();y=read();
if(op<) xg(x+,y+,op,);
else if(op==) printf("%d\n",find1(x+,y+,));
else printf("%d\n",find2(x+,y+,));
}
return ;
}
bzoj 1858: [Scoi2010]序列操作的更多相关文章
- (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...
- 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,要 ...
随机推荐
- iOS大神牛人的博客集合
王巍的博客:王巍目前在日本横滨任职于LINE.工作内容主要进行Unity3D开发,8小时之外经常进行iOS/Mac开发.他的陈列柜中已有多款应用,其中番茄工作法工具非常棒. http://onevca ...
- 在sqlserver存储过程中给in参数传带逗号值的办法,如传'1','2','3'这样的
最近在一项目修改中,要在存储过程中给in参数传值,语句写的也对,但怎么执行都得不出结果,如果把这语句直接赋值.执行,却能得出结果,很是奇怪,如: 直接执行select schoolname from ...
- 小希的数表2(用的for循环)
#include<iostream> 02.#include<algorithm> 03.using namespace std; 04. 05.bool cmp(int a, ...
- java中final,finally和finalize的区别
final,finally和finalize的区别: final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写 finally:是异 ...
- 【erlang】erlang几种生成随机数的方法
erlang有三个生产随机数的办法 random:uniform(). 这个函数是erlang库random模块提供的.一般都采用这个. 1> random:uniform(). 0.44358 ...
- Tomcat部署方式
tomcat中三种部署项目的方法 第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加: <Context path="/he ...
- PHP ftp使用
本文章来总结几个利用php中的ftp功能来实现通过FTP上传文件,有需要学习的朋友可参考参考.ftp_get() 函数从 FTP 服务器上下载一个文件.若成功则返回 true,失败则返回 false. ...
- nodejs:使用多处理器
nodejs是单线程,这意味着Node只能利用一个处理器来工作.但多数服务器都有多个核.好在nodejs提供了cluster模块,可以把任务分配给子进程.每个子进程有些特殊能力,比如能与其他子进程共享 ...
- Python动态生成变量
Python 也可以像javascript那样动态生成变量.我们看javascript的动态生成变量. var obj = {}; for (var i =0, len = 10; i < le ...
- Windows Phone 8.1 新特性 - 控件之应用程序栏
2014年4月3日的微软Build 2014 大会上,Windows Phone 8.1 正式发布.相较于Windows Phone 8,不论从用户还是开发者的角度,都产生了很大的变化.接下来我们会用 ...