感觉自己好像搞定了一个不得了得题呢。。

    对于这种区间性质合并的线段树,对于每个节点保存一下当前区间内1的个数,左右边界相邻的1个的个数与0的个数,还有当前区间最大连续的1和0的个数.

    合并的时候的细节:

    1.如果lson的右边界是1并且rson的左边界是1,那么当前节点的最大连续1的值应该更新为tr[n].res=max(tr[n].res,tr[LL].r+tr[RR].l);

    2.如果lson的连续1的个数等于它所表示的区间大小(这段区间的值全为1),那么当前节点的左区间连续1的个数应该更新为tr[n].l+=tr[RR].l;对于右区间的连续1的个数更新也一样。

    3.对于区间中0的性质更新与1一样

    更新时候的细节

    1.如果当前进行的是区间覆盖,那么是需要吧区间翻转的标记置0的。

    2.如果当前既需要更新区间覆盖与区间翻转,这时候只有一种可能情况就是区间覆盖是先进行赋值过的,所以在pushdown的时候区间覆盖应该先进行。

 #include<bits/stdc++.h>
using namespace std;
#define LL n<<1
#define RR n<<1|1
#define lson l,mid,LL
#define rson mid+1,r,RR
#define mid ((l+r)/2)
const int maxn=;
struct node{
int res,ret,num,l,r,ll,rr;//最长连续1的长度,最长连续0的长度,区间内1的个数,区间内左右边界连续1的个数,0的个数
};
node tr[maxn<<];
int lazy[maxn<<];//区间覆盖懒惰标记
int chan[maxn<<];//区间翻转懒惰标记
int a[maxn];
void up(int l,int r,int n){
tr[n].num=tr[LL].num+tr[RR].num;
tr[n].res=max(tr[LL].res,tr[RR].res);
tr[n].ret=max(tr[LL].ret,tr[RR].ret);
tr[n].l=tr[LL].l;
tr[n].ll=tr[LL].ll;
tr[n].r=tr[RR].r;
tr[n].rr=tr[RR].rr;
if(tr[LL].r&&tr[RR].l)
{
tr[n].res=max(tr[n].res,tr[LL].r+tr[RR].l);
if(mid-l+==tr[LL].res)
tr[n].l+=tr[RR].l;
if(r-mid==tr[RR].res)
tr[n].r+=tr[LL].r;
}
if(tr[LL].rr&&tr[RR].ll)
{
tr[n].ret=max(tr[n].ret,tr[LL].rr+tr[RR].ll);
if(mid-l+==tr[LL].ret)
tr[n].ll+=tr[RR].ll;
if(r-mid==tr[RR].ret)
tr[n].rr+=tr[LL].rr;
}
}
void built(int l,int r,int n){
lazy[n]=-;
chan[n]=;
if(l==r)
{
tr[n].l=tr[n].r=tr[n].res=tr[n].num=a[l];
tr[n].ret=tr[n].ll=tr[n].rr=!a[l];
return;
}
built(lson);
built(rson);
up(l,r,n);
}
void pushdown(int l,int r,int n){
if(lazy[n]!=-)
{
chan[LL]=chan[RR]=;
tr[LL].num=tr[LL].l=tr[LL].r=tr[LL].res=(mid-l+)*lazy[n];
tr[LL].ll=tr[LL].rr=tr[LL].ret=(mid-l+)*(!lazy[n]);
tr[RR].num=tr[RR].l=tr[RR].r=tr[RR].res=(r-mid)*lazy[n];
tr[RR].ll=tr[RR].rr=tr[RR].ret=(r-mid)*(!lazy[n]);
lazy[LL]=lazy[RR]=lazy[n];
lazy[n]=-;
}
if(chan[n])
{
chan[LL]^=;
chan[RR]^=;
tr[LL].num=mid-l+-tr[LL].num;
tr[RR].num=r-mid-tr[RR].num;
swap(tr[LL].res,tr[LL].ret);
swap(tr[LL].ll,tr[LL].l);
swap(tr[LL].rr,tr[LL].r);
swap(tr[RR].res,tr[RR].ret);
swap(tr[RR].ll,tr[RR].l);
swap(tr[RR].rr,tr[RR].r);
chan[n]=;
}
}
void update(int l,int r,int n,int left,int right,int num){
if(l>=left&&right>=r)
{
lazy[n]=num;
tr[n].num=num*(r-l+);
chan[n]=;
tr[n].l=tr[n].r=tr[n].res=(r-l+)*num;
tr[n].ll=tr[n].rr=tr[n].ret=(r-l+)*(!num);
return;
}
pushdown(l,r,n);
if(left<=mid)
update(lson,left,right,num);
if(right>mid)
update(rson,left,right,num);
up(l,r,n);
}
void change(int l,int r,int n,int left,int right){
if(l>=left&&right>=r)
{
chan[n]^=;
tr[n].num=(r-l+-tr[n].num);
swap(tr[n].res,tr[n].ret);
swap(tr[n].ll,tr[n].l);
swap(tr[n].rr,tr[n].r);
return;
}
pushdown(l,r,n);
if(left<=mid)
change(lson,left,right);
if(right>mid)
change(rson,left,right);
up(l,r,n);
}
int out1(int l,int r,int n,int left,int right){
if(l>=left&&right>=r)
return tr[n].num;
pushdown(l,r,n);
int res=;
if(left<=mid)
res+=out1(lson,left,right);
if(right>mid)
res+=out1(rson,left,right);
return res;
}
int out2(int l,int r,int n,int left,int right){
if(l>=left&&right>=r)
return tr[n].res;
pushdown(l,r,n);
int res=;
if(left<=mid)
res=max(res,out2(lson,left,right));
if(right>mid)
res=max(res,out2(rson,left,right));
if(tr[LL].r&&tr[RR].l&&mid>=left&&mid<right)
res=max(res,min(tr[LL].r,mid-left+)+min(tr[RR].l,right-mid));
return res;
}
int main(){
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
built(,n,);
for(int i=;i<=m;i++)
{ int x,y,z;
scanf("%d%d%d",&x,&y,&z);
y++;
z++;
if(x==)
update(,n,,y,z,);
else
if(x==)
update(,n,,y,z,);
else
if(x==)
change(,n,,y,z);
if(x==)
printf("%d\n",out1(,n,,y,z));
else
if(x==)
printf("%d\n",out2(,n,,y,z));
}
}
return ;
}

hdu3397 Sequence operation的更多相关文章

  1. hdu3397 Sequence operation 线段树

    hdu3397 Sequence operation #include <bits/stdc++.h> using namespace std; ; struct node { /// l ...

  2. hdu-3397 Sequence operation 线段树多种标记

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目大意: 0 a b表示a-b区间置为0 1 a b表示a-b区间置为1 2 a b表示a- ...

  3. hdu 3397 Sequence operation(很有意思的线段树题)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  4. Sequence operation(线段树区间多种操作)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. HDU 3397 Sequence operation(线段树)

    HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...

  6. 线段树 区间合并 F - Sequence operation

    F - Sequence operation 题解:这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,这个有两个地方要注意一下,一 ...

  7. 【30.01%】【hdu 3397】Sequence operation

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submissio ...

  8. (简单) HDU 3397 Sequence operation,线段树+区间合并。

    Problem Description lxhgww got a sequence contains n characters which are all '0's or '1's. We have ...

  9. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

随机推荐

  1. Android + eclipse +ADT安装完全教程

    最近几天没事做,网上看来看去突然就想弄个android来学学...  首先,是要下载android SDK,在http://developer.android.com/sdk/index.html这个 ...

  2. 数学之路(3)-机器学习(3)-机器学习算法-PCA

    PCA 主成分分析(Principal components analysis,PCA),维基百科给出一个较容易理解的定义:“PCA是一个正交化线性变换,把数据变换到一个新的坐标系统中,使得这一数据的 ...

  3. 关于时间的操作(JavaScript版)——年月日三级级联(默认依次显示请选择年、请选择月和请选择日)

    这篇博客和前一篇博客基本同样,仅仅是显示的默认值不同: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&quo ...

  4. WAS集群系列(6):集群搭建:步骤4:安装WAS升级软件

    逐步点击"下一步",注意一处流程,例如以下列举: "升级软件"安装的路径设置,建议与之前的WAS及IHS安装的绝对路径同样,例如以下所看到的: 逐步点击,完毕安 ...

  5. Hacker(24)----防范密码被轻易破解

    无论什么类型密码,用户在设置时都有非常小心,防止自己设置的密码被他人轻易破解.为保护重要的文件和资料,可采用加密工具进行加密,即可选择Win7系统自带的BitLocker,也可使用Internet中很 ...

  6. My way on Linux - [Shell基础] - Bash Shell中判断文件、目录是否存在或者判断其是否具有某类属性(权限)的常用方法

    Conditional Logic on Files # 判断文件是否存在及文件类型 -a file exists. #文件存在 -b file exists and is a block speci ...

  7. Javascript进阶篇——(DOM—节点---获取浏览器窗口可视区域大小+获取网页尺寸)—笔记整理

    浏览器窗口可视区域大小获得浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)的方法:一.对于IE9+.Chrome.Firefox.Opera 以及 Safari: • window.innerH ...

  8. createjs基础

    <canvas id="gameView" width="400px" height="400px" style="back ...

  9. IOS 图片模糊处理 ------ 直接代码 复制出去就可用 值得标记

    1. UIImage *imag = [UIImage imageNamed:@"img"]; /* --------------------使用 coreImg  ------- ...

  10. 改造百度UMeditor(UEditor-min)富文本编辑器的图片上传功能

    最近项目需要新增一个发布文章的模块,用的是百度的Ueditor富文本编辑器. 公司用的是阿里云的图片服务器,需要直接把文章中图片上传到服务器上,但是这个编辑器的上传图片是直接上传到Tomcat的根目录 ...