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 线段树||单调队列
非常裸的线段树 || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...
随机推荐
- 当执行太多不受信任的代码时,除去令人讨厌的大量 trycatch 的办法
如果方法 Condition 返回 true,则执行 IfTrue,否则执行 IfFalse,发生异常则执行 IfError. 通常是这样: try { if (Condition()) { try ...
- C plus plus study note (one)
What is an object ? Object = Entity ; Object may be -- visible or -- invisible Object is variable in ...
- sql server 维护计划与作业关系区别
sql server 维护计划与作业关系区别 对于二者的区别,你可以把维护计划看作是针对数据库进行维护的作业模板.自定义作业具有更广泛的用途,当然,也具有更复杂的操作.所以,如果 仅仅是做个数据库优化 ...
- php知识分享
PHP 获取ip地址代码汇总 ...
- uiscrollView UINavigation和uitabbar添加约束的问题
首先是层次问题, 我的storyboard中 底层是一个View(viewcontroller自带)上面添加了一个UIScrollview(添加约束, 上下左右全为0), 在UIScrollview上 ...
- JS中关于clientWidth offsetWidth scrollWidth 等的含义
网页可见区域宽: document.body.clientWidth;网页可见区域高: document.body.clientHeight;网页可见区域宽: document.body.offset ...
- canvas学习笔记:canvas对图片的像素级处理--ImageData的应用
学习了canvas的基本绘图功能后,惊喜的发现canvas对图片数据也有相当强大的处理功能,能够从像素级别操作位图,当然[lte ie8]不支持. 主要的函数有三个: ctx.createImageD ...
- 1千万英国用户被Cryptolocker勒索软件瞄准
英国国家打击犯罪调查局(NCA)发布国家紧急警报,警报一场大规模的垃圾邮件,这些邮件中包含了一款名为CryptoLocker的勒索程序,把目标瞄准了1千万英国的email用户,该程序会加密用户的文档, ...
- js 简繁体字转换
有些项目需要用到简体和繁体两种字体,在js前台进行转换比较方便而且显示速度没有延时 是一个比较好的解决方案. var _isFT_CS = 0// 简体 var _isFT_CT = 1// 繁体 v ...
- Xcode8 上架前属性列表添加权限
需要注意的是,权限的string,也就是提示语句也要设置,都设置好之后,一次就上传成功,可以添加构建版本了. <key>NSBluetoothPeripheralUsageDescr ...