标记会重叠需要判断.

 #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. android studio gradle结构项目引入本地代码

    1.首先需要用eclipse打开目标项目,file export,选择gradle file. 2.拷贝文件到as项目的根目录[可选] 3.找到as项目的根目录下 .idea目录,下面有个module ...

  2. ARM+LINUX 项目学习总结

    一.确定功能 二.系统移植 1. 根据具体板子修改u-boot (三星的开发板资料) 2. 根据具体板子和功能修改内核 (基本的驱动) 3. 移植busybox 三.驱动修改编写 四.应用编程 附1 ...

  3. Centos下MySQL主从同步配置

    说明:由于MySQL不同版本之间的(二进制日志)binlog格式可能会不一样, 因此最好的搭配组合是Master的MySQL版本和Slave的版本相同或者更低,Master的版本肯定不能高于Slave ...

  4. C++ 标准库string字符串的截取

    标准库的string有一个substr函数用来截取子字符串.一般使用时传入两个参数,第一个是开始的坐标(第一个字符是0),第二个是截取的长度. #include <iostream> #i ...

  5. 学jQuery Mobile后的感想

    jQuery Mobile是jQuery 在手机上和平板设备上的版本.jQuery Mobile 不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架.支持全球 ...

  6. tomcat重启脚本

    #!/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binexport JAVA_HOME=/opt/jd ...

  7. My97DatePickerBeta 日历插件

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

  8. node开发指南

    Node.js 能做什么 正如 JavaScript 为客户端而生,Node.js 为网络而生.Node.js 能做的远不止开发一个网站那么简单,使用 Node.js,你可以轻松地开发: 具有复杂逻辑 ...

  9. Flapper Bird的学习笔记(三)

    因为我有一个超屌的梦想,所以就绝不会做一个孬种的追梦人! 完成音效的添加 单例模式 游戏的状态切换 1. 单例模式 首先呢,说一下单例模式.何为单例?单例模式是一种常用的软件设计模式.在它的核心结构中 ...

  10. IOS开发_中遍历数组的方法及比较

    数组,做为一种常用的数据类型,频繁出现在编码中,其中肯定少不了对数组的遍历,本博文对数组遍历,进行一下自己的归纳,如果是大牛,一笑而过就好,互相学习,欢迎指正. 话不多说直接进入主题 首先创建一个数组 ...