BZOJ 1858 线段树
标记会重叠需要判断.
#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 线段树的更多相关文章
- BZOJ 1798 (线段树||分块)的标记合并
我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
- bzoj 3999 线段树区间提取 有序链剖
看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在O(nlog^3n)的时间复杂度内搞定 这道题用到的一些方法: 1. 可以将有关的线段提 ...
- bzoj 3211 线段树
开方操作最多进行5次就可以把出现的任何数变成1. 所以用线段树暴力修改,以后修改时只需看一下是否当前区间都是0或1,如果是那么就直接返回. /***************************** ...
- bzoj 1018 线段树维护连通性
本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护. 对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边 ...
- bzoj 3212 线段树
裸的线段树 /************************************************************** Problem: User: BLADEVIL Langua ...
- bzoj 2120 线段树套平衡树
先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...
- bzoj 1901 线段树套平衡树+二分答案查询
我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************* ...
- BZOJ 1012 线段树||单调队列
非常裸的线段树 || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...
随机推荐
- Unity 3D 正交相机(Orthographic)
1. Camera.aspect 表示摄像机显示区域的纵横比.宽高比,摄像机初始化的时候会默认设置成当前屏幕的宽高比,可以更改,也可以通过 Camera.ResetAspect 来重置. 2. Cam ...
- About “this” of Javascript
the 4 point about This: 1.the use of Object methods 2.the use of constructors 3.the use of ordinary ...
- uva 12549
12549 - Sentry Robots Time limit: 1.000 seconds We need to guard a set of points of interest using s ...
- vue-新建项目出错情况分析
1.状况一: 按照正常流程新建项目,最终运行npm run dev 的时候,就频频出错,最终找出问题原来在于部分依赖包丢失了,于是重新安装所需要的依赖包再运行项目便好了!
- sql 多行转换为一行
select 字段1, [val]=( select 字段2 +',' from 表名 as b where b.字段1 = a.字段1 for xml path('')) from 表名 as a ...
- daydayup1 codeforces141c
题意:给定n个数字,代表每个人前面有几个人比他高,让你构造一个height数组,满足条件 思路:直接贪心就好,假设到第i个人,设他的高度为i-a[i]+1,前面比他高的人每个人的高度加1
- Erlang中如何在同一台机器上运行多个erlang节点?
首先打开shell,然后在打开cmd输入:erl -sname bilbo 这样就启动了一个gandal的erlang节点. 如图:
- μC/OS-Ⅲ系统的任务切换和任务调度
一.任务切换 在操作系统中当任务需要从一个任务切换到另外一个任务时,要将当前任务的现场保存到当前任务的堆栈中(当前任务现场主要指CPU相关寄存器),然后回复新任务的现场并执行新任务.这个叫做上下文切换 ...
- 推荐一个实用的css工具
后台程序员整天在和数据打交道,天天的活就是抱着mysql抠数据,如果让他去写网站的样式,就让人感觉力不从心,所以推荐一个twitter的团队开发的东西,几乎囊括了网站所需的样式,http://www. ...
- 写入标题使用依赖注入Title的setTitle方法
1. 声明 Generator的声明方式类似一般的函数声明,只是多了个*号,并且一般可以在函数内看到yield关键字 function* showWords() { yield 'one'; yiel ...