/*
一开始维护了两个标记 开了两个数组
想的是 可能当前两种操作都要做
但是太复杂了 不好处理
其实 当前要做的标记可以只有一个 我们在Insert的时候 要打的标记是2即翻转区间: 1.如果原来是区间赋值1 先赋值1在翻转 问题不大 标记变 1-1=0
2.如果原来是区间赋值0 同上 问题不大 标记 1-0=1
3.如果原始是区间翻转 抵消1-2=-1
4.如果原来是-1 无标记 就打上 1-(-1)=2 这个时候要先把区间的01信息互换 要打的标记是01即区间赋值
就无视之前的翻转操作 直接打上标记更新k 然后Up的时候(标记下方)就只有一个标记
1.如果是2 就下放 改了左右儿子 然后同上进行标记改变
2.如果是01
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#define lc k*2
#define rc k*2+1
#define len (r-l+1)
#define mid (l+r)/2
#define maxn 400010
using namespace std;
int T,I,n,m,s1[maxn],s0[maxn],l1[maxn],l0[maxn],r1[maxn],r0[maxn],mx1[maxn],mx0[maxn],a[maxn];
void Swap(int k,int l,int r){
a[k]=-a[k];swap(s1[k],s0[k]);swap(l1[k],l0[k]);
swap(r1[k],r0[k]);swap(mx1[k],mx0[k]);
}
void Up(int k,int l,int r){
if(a[k]==){
a[k]=-;Swap(lc,l,mid);Swap(rc,mid+,r);return;
}
a[lc]=a[rc]=a[k];
s1[lc]=(mid-l+)*a[k];s0[lc]=(mid-l+)*(a[k]^);
s1[rc]=(r-mid)*a[k];s0[rc]=(r-mid)*(a[k]^);
l1[lc]=(mid-l+)*a[k];l0[lc]=(mid-l+)*(a[k]^);
l1[rc]=(r-mid)*a[k];l0[rc]=(r-mid)*(a[k]^);
r1[lc]=(mid-l+)*a[k];r0[lc]=(mid-l+)*(a[k]^);
r1[rc]=(r-mid)*a[k];r0[rc]=(r-mid)*(a[k]^);
mx1[lc]=(mid-l+)*a[k];mx0[lc]=(mid-l+)*(a[k]^);
mx1[rc]=(r-mid)*a[k];mx0[rc]=(r-mid)*(a[k]^);
a[k]=-;
}
void Insert(int k,int l,int r,int x,int y,int z){
if(x<=l&&y>=r){
if(z==)Swap(k,l,r);
else {
a[k]=z;s1[k]=len*z;s0[k]=len*(z^);mx1[k]=len*z;mx0[k]=len*(z^);
l1[k]=len*z;l0[k]=len*(z^);r1[k]=len*z;r0[k]=len*(z^);
}
return;
}
if(a[k]!=-)Up(k,l,r);
if(x<=mid)Insert(lc,l,mid,x,y,z);
if(y>mid)Insert(rc,mid+,r,x,y,z);
s1[k]=s1[lc]+s1[rc];s0[k]=s0[lc]+s0[rc];
l1[k]=l1[lc]+(l1[lc]==mid-l+)*l1[rc];
r1[k]=r1[rc]+(r1[rc]==r-mid)*r1[lc];
l0[k]=l0[lc]+(l0[lc]==mid-l+)*l0[rc];
r0[k]=r0[rc]+(r0[rc]==r-mid)*r0[lc];
mx1[k]=max(mx1[lc],max(mx1[rc],r1[lc]+l1[rc]));
mx0[k]=max(mx0[lc],max(mx0[rc],r0[lc]+l0[rc]));
}
int Query1(int k,int l,int r,int x,int y){
if(x<=l&&y>=r)return s1[k];
int res=;
if(a[k]!=-)Up(k,l,r);
if(x<=mid)res+=Query1(lc,l,mid,x,y);
if(y>mid)res+=Query1(rc,mid+,r,x,y);
return res;
}
int Query2(int k,int l,int r,int x,int y){
if(x<=l&&y>=r)return mx1[k];
if(a[k]!=-)Up(k,l,r);
int res=;
if(x<=mid)res=max(res,Query2(lc,l,mid,x,y));
if(y>mid)res=max(res,Query2(rc,mid+,r,x,y));
if(x<=mid&&y>mid)res=max(res,min(mid-x+,r1[lc])+min(y-mid,l1[rc]));
return res;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);int x,y,z;
for(int i=;i<=n*;i++)a[i]=-;
for(int i=;i<=n;i++){
scanf("%d",&x);Insert(,,n,i,i,x);
}
for(I=;I<=m;I++){
scanf("%d%d%d",&z,&x,&y);x++;y++;
if(z==||z==||z==)Insert(,,n,x,y,z);
if(z==)printf("%d\n",Query1(,,n,x,y));
if(z==)printf("%d\n",Query2(,,n,x,y));
}
}
return ;
}

HDU 3397 Sequence operation 多标记线段树的更多相关文章

  1. 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变 ...

  2. hdu 3397 Sequence operation (线段树 区间合并 多重标记)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...

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

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

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

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

  5. 【线段树】HDU 3397 Sequence operation 区间合并

    操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...

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

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

  7. hdu 3397 Sequence operation 线段树

    题目链接 给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数. 需要将数组开成二维的, 然后区间0, 1翻转只 ...

  8. HDU 3397"Sequence operation"(线段树区间和并)

    传送门 •题意 给你一个仅包含 0 和 1 的序列: 在这个序列上有如下操作: (1)0 a b : 将 [a,b] 区间的数置 0: (2)1 a b : 将 [a,b] 区间的数置 1: (3)2 ...

  9. hdu 3397 Sequence operation 线段树 区间更新 区间合并

    题意: 5种操作,所有数字都为0或1 0 a b:将[a,b]置0 1 a b:将[a,b]置1 2 a b:[a,b]中的0和1互换 3 a b:查询[a,b]中的1的数量 4 a b:查询[a,b ...

随机推荐

  1. 在Yosemite中创建个人站点

    Yosemite变动很大,随之而来的就是一堆坑,之前在旧版OS中有效的方法在新版OS上已经不起作用了,创建个人站点就是一例. Mac OS内置Apache,安装目录在/etc/apache2/,etc ...

  2. Caffe2:ubuntu修改链接方式ln

    参考:文件和目录命令-文件重定向 ln 使用caffe2,产生了此种情况: from caffe2.python import workspace >>WARNING:root:This ...

  3. OpenCV:使用OpenCV3随机森林进行统计特征多类分析

    原文链接:在opencv3中的机器学习算法练习:对OCR进行分类 本文贴出的代码为自己的训练集所用,作为参考.可运行demo程序请拜访原作者. CNN作为图像识别和检测器,在分析物体结构分布的多类识别 ...

  4. HTTP常见状态码(404、400、500)等错误

    一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 详细分解: 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 ...

  5. Python 之pdb调试

    # 调试方式一:python -m pdb test.py # 相关命令: # l 查看当前代码 # n 向下执行一行代码 # c continue继续执行代码 # b break + 行数 添加断点 ...

  6. linux修改hosts配置

    参考 https://blog.csdn.net/qq_15192373/article/details/81093542 1. terminal中输入: sudo gedit /etc/hosts ...

  7. Java中接口与接口和类之间的关系

    接口和接口之间的关系 继承关系 可以多继承,并且可以多层继承 注意: 1.如果多个父接口中有同名的抽象方法,那么子接口只需要实现一次即可 2.如果多个父接口中有同名的默认方法,那么子接口必须重写默认方 ...

  8. 报错:command not found

    linux中如果是最小化安装的系统,执行命令的时候很多会出现没找到命令 [root@localhost ~]# mtr -bash: mtr: command not found [root@loca ...

  9. odoo 权限杂记

    最近做一个任务督办模块,涉及到一些权限问题,折磨了几天,终于是解决了. 任务表中关联了hr_employee,分别有默认字段创建人,Many2one的发布人.监督人和Many2many类型的主责人,这 ...

  10. List多字段排序,orderBy,ThenBy

    List排序问题,orderBy,ThenBy 1.List中一个字段排序 前几天做的项目中,获取的List<T>需要用某个字段来进行排序,困扰了很久.用OrderBy解决了.具体是这样的 ...