合并中间那块的时候没取max……WAWAWA

在线段树上维护一堆东西,分别是len区间长度,sm区间内1的个数,ll0区间从左开始最长连续0,ml0区间中间最长连续0,rl0区间从右开始最长连续0,ll1区间从左开始最长连续1,ml1区间中间最长连续1,rl1区间从右开始最长连续1(起始这六个东西可以存成三个数组,这样操作起来比较方便),lz标记区间赋值(没有赋值的时候为-1),f标记区间取反

仔细思考一下优先级,赋值>取反,所以lz标记不为-1时,f标记为0

sm,len的和并很好说,以下x表示0或1,llx的合并是左儿子的llx,如果左儿子全是x的话就加上右儿子的llx,rlx同理,mlx是max(左儿子的rlx+右儿子的llx,左儿子的mlx,右儿子的mlx)

注意细节不要手残打错!

#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
int n,m,a[N];
struct xds
{
int l,r,len,sm,ll[2],ml[2],rl[2],f,lz;
}t[N<<2];
struct qwe
{
int l,m,r;
qwe(int L=0,int M=0,int R=0)
{
l=L,m=M,r=R;
}
};
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void ud(int ro)
{
t[ro].sm=t[ro<<1].sm+t[ro<<1|1].sm;
t[ro].ll[0]=t[ro<<1].ll[0]+((t[ro<<1].sm==0)?t[ro<<1|1].ll[0]:0);
t[ro].ml[0]=max(t[ro<<1].rl[0]+t[ro<<1|1].ll[0],max(t[ro<<1].ml[0],t[ro<<1|1].ml[0]));
t[ro].rl[0]=t[ro<<1|1].rl[0]+((t[ro<<1|1].sm==0)?t[ro<<1].rl[0]:0);
t[ro].ll[1]=t[ro<<1].ll[1]+((t[ro<<1].sm==t[ro<<1].len)?t[ro<<1|1].ll[1]:0);
t[ro].ml[1]=max(t[ro<<1].rl[1]+t[ro<<1|1].ll[1],max(t[ro<<1].ml[1],t[ro<<1|1].ml[1]));
t[ro].rl[1]=t[ro<<1|1].rl[1]+((t[ro<<1|1].sm==t[ro<<1|1].len)?t[ro<<1].rl[1]:0);
}
void pd(int ro)
{
if(t[ro].lz!=-1)
{
t[ro<<1].lz=t[ro].lz,t[ro<<1].f=0;
t[ro<<1].sm=t[ro].lz?t[ro<<1].len:0;
t[ro<<1].ll[t[ro].lz]=t[ro<<1].ml[t[ro].lz]=t[ro<<1].rl[t[ro].lz]=t[ro<<1].len;
t[ro<<1].ll[t[ro].lz^1]=t[ro<<1].ml[t[ro].lz^1]=t[ro<<1].rl[t[ro].lz^1]=0;
t[ro<<1|1].lz=t[ro].lz,t[ro<<1|1].f=0;
t[ro<<1|1].sm=t[ro].lz?t[ro<<1|1].len:0;
t[ro<<1|1].ll[t[ro].lz]=t[ro<<1|1].ml[t[ro].lz]=t[ro<<1|1].rl[t[ro].lz]=t[ro<<1|1].len;
t[ro<<1|1].ll[t[ro].lz^1]=t[ro<<1|1].ml[t[ro].lz^1]=t[ro<<1|1].rl[t[ro].lz^1]=0;
t[ro].lz=-1;
}
if(t[ro].f)
{
t[ro<<1].f^=1;
swap(t[ro<<1].ll[0],t[ro<<1].ll[1]);
swap(t[ro<<1].ml[0],t[ro<<1].ml[1]);
swap(t[ro<<1].rl[0],t[ro<<1].rl[1]);
t[ro<<1].sm=t[ro<<1].len-t[ro<<1].sm;
if(t[ro<<1].lz!=-1)
t[ro<<1].lz^=1,t[ro<<1].f=0;
t[ro<<1|1].f^=1;
swap(t[ro<<1|1].ll[0],t[ro<<1|1].ll[1]);
swap(t[ro<<1|1].ml[0],t[ro<<1|1].ml[1]);
swap(t[ro<<1|1].rl[0],t[ro<<1|1].rl[1]);
t[ro<<1|1].sm=t[ro<<1|1].len-t[ro<<1|1].sm;
if(t[ro<<1|1].lz!=-1)
t[ro<<1|1].lz^=1,t[ro<<1|1].f=0;
t[ro].f=0;
}
}
void build(int ro,int l,int r)
{
t[ro].l=l,t[ro].r=r,t[ro].len=r-l+1,t[ro].lz=-1;
if(l==r)
{
t[ro].sm=a[l];
t[ro].ll[a[l]]=t[ro].ml[a[l]]=t[ro].rl[a[l]]=1;
return;
}
int mid=(l+r)>>1;
build(ro<<1,l,mid);
build(ro<<1|1,mid+1,r);
ud(ro);
}
void update(int ro,int l,int r,int v)
{
if(t[ro].l==l&&t[ro].r==r)
{
t[ro].lz=v,t[ro].f=0;
t[ro].sm=v?t[ro].len:0;
t[ro].ll[v]=t[ro].ml[v]=t[ro].rl[v]=t[ro].len;
t[ro].ll[v^1]=t[ro].ml[v^1]=t[ro].rl[v^1]=0;
return;
}
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
update(ro<<1,l,r,v);
else if(l>mid)
update(ro<<1|1,l,r,v);
else
update(ro<<1,l,mid,v),update(ro<<1|1,mid+1,r,v);
ud(ro);
}
void fan(int ro,int l,int r)
{
if(t[ro].l==l&&t[ro].r==r)
{
t[ro].f^=1;
swap(t[ro].ll[0],t[ro].ll[1]);
swap(t[ro].ml[0],t[ro].ml[1]);
swap(t[ro].rl[0],t[ro].rl[1]);
t[ro].sm=t[ro].len-t[ro].sm;
if(t[ro].lz!=-1)
t[ro].lz^=1,t[ro].f=0;
return;
}
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
fan(ro<<1,l,r);
else if(l>mid)
fan(ro<<1|1,l,r);
else
fan(ro<<1,l,mid),fan(ro<<1|1,mid+1,r);
ud(ro);
}
int ques(int ro,int l,int r)
{
if(t[ro].l==l&&t[ro].r==r)
return t[ro].sm;
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
return ques(ro<<1,l,r);
else if(l>mid)
return ques(ro<<1|1,l,r);
else
return ques(ro<<1,l,mid)+ques(ro<<1|1,mid+1,r);
}
qwe lian(int ro,int l,int r)
{
if(t[ro].l==l&&t[ro].r==r)
return qwe(t[ro].ll[1],t[ro].ml[1],t[ro].rl[1]);
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
return lian(ro<<1,l,r);
else if(l>mid)
return lian(ro<<1|1,l,r);
else
{
int len1=mid-l+1,len2=r-mid,ll,ml,rl;
qwe a=lian(ro<<1,l,mid),b=lian(ro<<1|1,mid+1,r);
ll=a.l+((a.l==len1)?b.l:0);
ml=max(a.r+b.l,max(a.m,b.m));
rl=b.r+((b.r==len2)?a.r:0);
return qwe(ll,ml,rl);
}
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
build(1,1,n);
while(m--)
{
int o=read(),l=read()+1,r=read()+1;
if(o==0)
update(1,l,r,0);
else if(o==1)
update(1,l,r,1);
else if(o==2)
fan(1,l,r);
else if(o==3)
printf("%d\n",ques(1,l,r));
else
printf("%d\n",lian(1,l,r).m);
}
return 0;
}

bzoj 1858: [Scoi2010]序列操作【线段树】的更多相关文章

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

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

  2. (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作

    二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...

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

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

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

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

  5. 【bzoj1858】[Scoi2010]序列操作 线段树区间合并

    题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...

  6. Luogu P2572 [SCOI2010]序列操作 线段树。。

    咕咕了...于是借鉴了小粉兔的做法ORZ... 其实就是维护最大子段和的线段树,但上面又多了一些操作....QWQ 维护8个信息:1/0的个数(sum),左/右边起1/0的最长长度(ls,rs),整段 ...

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

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1858 线段树...调了一个上午...(后面带 // 的都是改出来的) lazy 标记的下放好 ...

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

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

  9. 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树

    正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...

  10. [SCOI2010]序列操作 线段树

    ---题面--- 题解: 在考场上打的这道题,出人意料的很快就打完了?! 直接用线段树,维护几个东西: 1,lazy标记 : 表示区间赋值 2,mark标记:表示区间翻转 3,l1:前缀最长连续的1的 ...

随机推荐

  1. AS3实现ToolTip效果

    AS3核心类中没有ToolTip类,Flex中的ToolTip类没法用在AS3工程中,Aswing的JToolTip不错,不过如果仅仅为了使用这一个类而导入Aswing就不太明智了.由于最近的项目需要 ...

  2. 《APP开发》APP规范实例-详细的UI设计方法

    对了一个APP开发初手来说,可能心里有很多的疑惑: 屏幕设计为多宽,宽度是不是应该设置为百分比; 按钮大小多大,怎么排列,文字字体用多大的?什么字体显示好看?图标多大,怎么用色?界面怎么布局?等等很多 ...

  3. 从零开始写STL—模板元编程之any

    any class any; (since C++17) The class any describes a type-safe container for single values of any ...

  4. Wannafly挑战赛4

    A(枚举) =w= B(枚举) 分析: 枚举每一位,考虑每位贡献,就是相当于在一段区间内找有多少1在奇数位上,有多少个1在偶数位上,维护一下各自前缀和就行了 时间复杂度O(32n) C(签到) D(d ...

  5. 百亿级企业级 RPC 框架开源了!

    今天给大家介绍给一款性能卓越的 RPC 开源框架,其作者就是我推荐每个 Java 程序员都应该看的<Java 生态核心知识点整理>的原作者张玉龙. 说实话我第一次看到这个资料的时候,就感觉 ...

  6. OSChinaclient源代码学习(3)--轮询机制的实现

    主要以OSChina Androidclient源代码中Notice的轮询机制进行解读. 一.基础知识 一般IM(即使通讯)的实现有两种方式:推送和轮询,推送就是server主动向client发送消息 ...

  7. 利用百度地图Android sdk高仿微信发送位置功能

    接触了百度地图开发平台半个月了,这2天试着模仿了微信给好友发送位置功能,对百度地图的操作能力又上了一个台阶 (假设须要完整demo.请评论留下邮箱) (眼下源代码已经不发送,假设须要源代码.加qq31 ...

  8. 【转】PHP实现系统编程(四)--- 本地套接字(Unix Domain Socket)

    原文:http://blog.csdn.net/zhang197093/article/details/78143687?locationNum=6&fps=1 --------------- ...

  9. 微信小程序-setData()方法

    一般setData方法多用于点击后改变页面信息或者刷新后与后台交互获取最新的信息 注意: 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致 ...

  10. webpack-Dependency Graph(依赖图)

    依赖图(Dependency Graph) 任何时候,一个文件依赖于另一个文件,webpack 就把此视为文件之间有依赖关系. 这使得 webpack 可以接收非代码资源(non-code asset ...