标记会重叠需要判断.

 #include <bits/stdc++.h>
using namespace std;
inline int Max(int x,int y) {return x>y?x:y;}
inline int Max3(int x,int y,int z) {return Max(x,Max(y,z));}
inline void Swap(int &x,int &y) {int t=x;x=y;y=t;}
//===========================================
const int Maxn=;
struct Node
{
int Len,Size0,Size1,l0,l1,r0,r1,Max0,Max1,Tag,Rev;
}Tree[Maxn<<];
int n,m,l,r,Type,a[Maxn];
inline void Push_Up(int o)
{
Tree[o].Len=Tree[o<<].Len+Tree[o<<|].Len;
Tree[o].Size0=Tree[o<<].Size0+Tree[o<<|].Size0;
Tree[o].Size1=Tree[o<<].Size1+Tree[o<<|].Size1;
Tree[o].l0=(Tree[o<<].Len!=Tree[o<<].l0)?Tree[o<<].l0:Tree[o<<].Len+Tree[o<<|].l0;
Tree[o].r0=(Tree[o<<|].Len!=Tree[o<<|].r0)?Tree[o<<|].r0:Tree[o<<|].Len+Tree[o<<].r0;
Tree[o].l1=(Tree[o<<].Len!=Tree[o<<].l1)?Tree[o<<].l1:Tree[o<<].Len+Tree[o<<|].l1;
Tree[o].r1=(Tree[o<<|].Len!=Tree[o<<|].r1)?Tree[o<<|].r1:Tree[o<<|].Len+Tree[o<<].r1;
Tree[o].Max0=Max3(Tree[o<<].r0+Tree[o<<|].l0,Tree[o<<].Max0,Tree[o<<|].Max0);
Tree[o].Max1=Max3(Tree[o<<].r1+Tree[o<<|].l1,Tree[o<<].Max1,Tree[o<<|].Max1);
}
inline void Swap_Tree(int o)
{
Swap(Tree[o].l1,Tree[o].l0),Swap(Tree[o].r0,Tree[o].r1),Swap(Tree[o].Max0,Tree[o].Max1),Swap(Tree[o].Size0,Tree[o].Size1);
}
inline void Update(int o,int v)
{
if (v==) Tree[o].Size0=Tree[o].l0=Tree[o].r0=Tree[o].Max0=Tree[o].Len,Tree[o].Size1=Tree[o].l1=Tree[o].r1=Tree[o].Max1=;
if (v==) Tree[o].Size0=Tree[o].l0=Tree[o].r0=Tree[o].Max0=,Tree[o].Size1=Tree[o].l1=Tree[o].r1=Tree[o].Max1=Tree[o].Len;
}
inline void Push_Down(int o)
{
if (Tree[o].Rev)
{
if (Tree[o<<].Tag) Tree[o<<].Tag=(Tree[o<<].Tag==)?:,Swap_Tree(o<<); else Tree[o<<].Rev^=,Swap_Tree(o<<);
if (Tree[o<<|].Tag) Tree[o<<|].Tag=(Tree[o<<|].Tag==)?:,Swap_Tree(o<<|); else Tree[o<<|].Rev^=,Swap_Tree(o<<|);
Tree[o].Rev=;
}
if (Tree[o].Tag)
{
Update(o<<,Tree[o].Tag),Update(o<<|,Tree[o].Tag);
Tree[o<<].Tag=Tree[o<<|].Tag=Tree[o].Tag;
Tree[o].Tag=;
} }
void Build(int o,int l,int r)
{
if (l==r)
{
Tree[o].Len=;
if (a[l]==) Tree[o].l0=Tree[o].r0=Tree[o].Max0=Tree[o].Size0=;
if (a[l]==) Tree[o].l1=Tree[o].r1=Tree[o].Max1=Tree[o].Size1=;
return;
}
int mid=(l+r)>>;
Build(o<<,l,mid),Build(o<<|,mid+,r);
Push_Up(o);
}
void Modify(int o,int l,int r,int p,int q,int v)
{
if (l==p && r==q)
{
if (Tree[o].Rev) Tree[o].Rev=;
Update(o,v); Tree[o].Tag=v;
return;
}
int mid=(l+r)>>;
Push_Down(o);
if (q<=mid) Modify(o<<,l,mid,p,q,v);
if (p>=mid+) Modify(o<<|,mid+,r,p,q,v);
if (p<=mid && q>=mid+) Modify(o<<,l,mid,p,mid,v),Modify(o<<|,mid+,r,mid+,q,v);
Push_Up(o);
}
void Revese(int o,int l,int r,int p,int q)
{
Push_Down(o);
if (l==p && r==q)
{
if (Tree[o].Tag) {Tree[o].Tag=(Tree[o].Tag==)?:; Swap_Tree(o); return;}
Tree[o].Rev^=;
Swap_Tree(o);
return;
}
int mid=(l+r)>>;
if (q<=mid) Revese(o<<,l,mid,p,q);
if (p>=mid+) Revese(o<<|,mid+,r,p,q);
if (p<=mid && q>=mid+) Revese(o<<,l,mid,p,mid),Revese(o<<|,mid+,r,mid+,q);
Push_Up(o);
}
int Query_Size(int o,int l,int r,int p,int q)
{
Push_Down(o);
if (l==p && r==q) return Tree[o].Size1;
int mid=(l+r)>>;
if (q<=mid) return Query_Size(o<<,l,mid,p,q);
if (p>=mid+) return Query_Size(o<<|,mid+,r,p,q);
return Query_Size(o<<,l,mid,p,mid)+Query_Size(o<<|,mid+,r,mid+,q);
}
Node Query_Len(int o,int l,int r,int p,int q)
{
Push_Down(o);
if (l==p && r==q) return Tree[o];
int mid=(l+r)>>;
if (q<=mid) return Query_Len(o<<,l,mid,p,q);
if (p>=mid+) return Query_Len(o<<|,mid+,r,p,q);
Node L=Query_Len(o<<,l,mid,p,mid);
Node R=Query_Len(o<<|,mid+,r,mid+,q);
Node M;
M.Len=L.Len+R.Len;
M.l1=(L.Len!=L.l1)?L.l1:L.Len+R.l1;
M.r1=(R.Len!=R.r1)?R.r1:R.Len+L.r1;
M.Max1=Max3(L.r1+R.l1,L.Max1,R.Max1);
return M;
}
int main()
{
// freopen("c.in","r",stdin);
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
Build(,,n);
for (int i=;i<=m;i++)
{
scanf("%d%d%d",&Type,&l,&r); l++,r++;
if (Type==) Modify(,,n,l,r,);
if (Type==) Modify(,,n,l,r,);
if (Type==) Revese(,,n,l,r);
if (Type==) printf("%d\n",Query_Size(,,n,l,r));
if (Type==) printf("%d\n",Query_Len(,,n,l,r).Max1);
}
return ;
}

C++

BZOJ 1858 线段树的更多相关文章

  1. BZOJ 1798 (线段树||分块)的标记合并

    我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...

  2. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  3. bzoj 3999 线段树区间提取 有序链剖

    看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在O(nlog^3n)的时间复杂度内搞定 这道题用到的一些方法: 1. 可以将有关的线段提 ...

  4. bzoj 3211 线段树

    开方操作最多进行5次就可以把出现的任何数变成1. 所以用线段树暴力修改,以后修改时只需看一下是否当前区间都是0或1,如果是那么就直接返回. /***************************** ...

  5. bzoj 1018 线段树维护连通性

    本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护. 对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边 ...

  6. bzoj 3212 线段树

    裸的线段树 /************************************************************** Problem: User: BLADEVIL Langua ...

  7. bzoj 2120 线段树套平衡树

    先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...

  8. bzoj 1901 线段树套平衡树+二分答案查询

    我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************* ...

  9. BZOJ 1012 线段树||单调队列

    非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...

随机推荐

  1. IE兼容问题,各类css hack代码(亲测有效)

    现在大部分企业对浏览器兼容要求是IE7+或者IE8+,要求IE6的很少,此处一并写出. IE6: _margin-top: 20px; IE6+IE7: *margin-top: 20px; +mar ...

  2. java中使用poi导入导出excel文件_并自定义日期格式

    Apache POI项目的使命是创造和保持java API操纵各种文件格式基于Office Open XML标准(OOXML)和微软的OLE复合文档格式(OLE2)2.总之,你可以读写Excel文件使 ...

  3. uva 10801(最短路)

    题目大意: 有一层不超过100层的大楼, 有n个电梯,它们的速度都不同. 而且每个电梯只能到达指定的那些楼层,而且它们都有各自的速度(即上升一层或下降一层所用的时间). 如果一个人在某层走出电梯,要换 ...

  4. Python模块学习笔记

    1.作用域 私有private:用'_x'或'__xx'表示,如,_a,__ab; 公有public: 如 a,b; 特殊变量,可被直接引用,如:__author__,__name__,命名变量时一般 ...

  5. 2014 年最热门的国人开发开源软件TOP 100

    不知道从什么时候开始,很多一说起国产好像就非常愤慨,其实大可不必.做开源中国六年有余,这六年时间国内的开源蓬勃发展,从一开始的使用到贡献,到推出自己很多的开源软件,而且还有很多软件被国外认可.中国是开 ...

  6. qt越来越好了

    qml中所有的商业控件都开源了,详见: import QtQuick.Extras 1.4 以前自己实现的时候实现了半天.

  7. ASP.NET MVC4 请不要将你的Control命名为APIController

    今天小猪就遇到了这个坑,虽然小猪知道MVC4已经默认提供了APIController类,这样如果某Control继承自这个APIController的话会使用其自带的REST服务等等,但是之前小猪想我 ...

  8. 繁星——JQuery选择器之层级

    [ancestor descendant] 在给定元素下匹配所有后代元素.这个选择器的使用概率相当之高,使用示例如下: //HTML代码: <div id='div01'> <inp ...

  9. js控制键盘只能输入数字和退格键,delete键

    function numbText(e){ if(e&& e.stopPropagation){ code= e.which; }else{ code= window.event.ke ...

  10. STEP模块——电子琴

    电子琴原理 什么是声音?上过初中的朋友都知道声音是由震动所产生的.一定频率的震动就产生了一定频率的声音. 理论研究第一步,让喇叭发出do re mi fa sol la si的音,我们先不管do的频率 ...