调了很久的代码。。注意区间翻转和覆盖的操作互相的影响

/*
区间替换操作怎么搞?
应该是加个tag标记
如果整个区间都是0|1,那么把若有tag的话直接set1|0即可,也不用设置tag标记
反之要设置tag标记,设置了tag标记的区间mx0和mx1要对换
lazy标记可以覆盖tag
mx0,mx1表示区间0,1最大连续,lmx0,lmx1表示区间左连续,rmx0,rmx1表示区间右连续
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int t,n,m,a[maxn]; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int mx0[maxn<<],mx1[maxn<<],lmx0[maxn<<],rmx0[maxn<<],lmx1[maxn<<],rmx1[maxn<<];
int sum[maxn<<],lazy[maxn<<],tag[maxn<<];
void set0(int l,int r,int rt){tag[rt]=;lazy[rt]=;mx0[rt]=lmx0[rt]=rmx0[rt]=r-l+;sum[rt]=mx1[rt]=lmx1[rt]=rmx1[rt]=;}
void set1(int l,int r,int rt){tag[rt]=;lazy[rt]=;mx0[rt]=lmx0[rt]=rmx0[rt]=;sum[rt]=mx1[rt]=lmx1[rt]=rmx1[rt]=r-l+;}
void rev(int l,int r,int rt){
if(lazy[rt]==)set1(l,r,rt);
else if(lazy[rt]==)set0(l,r,rt);
else {
tag[rt]^=;
sum[rt]=r-l+-sum[rt];
swap(mx0[rt],mx1[rt]);
swap(lmx0[rt],lmx1[rt]);
swap(rmx0[rt],rmx1[rt]);
}
}
void pushup(int l,int r,int rt){
int m=l+r>>;
lmx0[rt]=lmx0[rt<<],rmx0[rt]=rmx0[rt<<|];
mx0[rt]=max(mx0[rt<<],mx0[rt<<|]);
if(rmx0[rt<<]==m-l+)lmx0[rt]=lmx0[rt<<|]+m-l+;
if(lmx0[rt<<|]==r-m)rmx0[rt]=rmx0[rt<<]+r-m;
mx0[rt]=max(mx0[rt],max(lmx0[rt],rmx0[rt]));
mx0[rt]=max(mx0[rt],rmx0[rt<<]+lmx0[rt<<|]); lmx1[rt]=lmx1[rt<<],rmx1[rt]=rmx1[rt<<|];
mx1[rt]=max(mx1[rt<<],mx1[rt<<|]);
if(rmx1[rt<<]==m-l+)lmx1[rt]=lmx1[rt<<|]+m-l+;
if(lmx1[rt<<|]==r-m)rmx1[rt]=rmx1[rt<<]+r-m;
mx1[rt]=max(mx1[rt],max(lmx1[rt],rmx1[rt]));
mx1[rt]=max(mx1[rt],rmx1[rt<<]+lmx1[rt<<|]); sum[rt]=sum[rt<<]+sum[rt<<|];
}
void pushdown(int l,int r,int rt){
int m=l+r>>;
if(lazy[rt]==){set0(lson);set0(rson);lazy[rt]=-;return;}
else if(lazy[rt]==){set1(lson),set1(rson);lazy[rt]=-;return;}
else if(tag[rt]){rev(lson);rev(rson);tag[rt]=;return;}
}
void build(int l,int r,int rt){
lazy[rt]=-;
tag[rt]=sum[rt]=;
if(l==r){
if(a[l]==){mx0[rt]=lmx0[rt]=rmx0[rt]=;mx1[rt]=lmx1[rt]=rmx1[rt]=;}
else{mx0[rt]=lmx0[rt]=rmx0[rt]=;mx1[rt]=lmx1[rt]=rmx1[rt]=sum[rt]=;}
return;
}
int m=l+r>>;
build(lson);build(rson);
pushup(l,r,rt);
}
void update0(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){set0(l,r,rt);return;}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m)update0(L,R,lson);
if(R>m)update0(L,R,rson);
pushup(l,r,rt);
}
void update1(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){set1(l,r,rt);return;}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m)update1(L,R,lson);
if(R>m)update1(L,R,rson);
pushup(l,r,rt);
}
void update2(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){rev(l,r,rt);return;}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m)update2(L,R,lson);
if(R>m)update2(L,R,rson);
pushup(l,r,rt);
}
int query1(int L,int R,int l,int r,int rt){
if(L<=l &&R>=r){return sum[rt];}
int m=l+r>>,res=;
pushdown(l,r,rt);
if(L<=m)res+=query1(L,R,lson);
if(R>m)res+=query1(L,R,rson);
pushup(l,r,rt);
return res;
}
int query2(int L,int R,int l,int r,int rt){
if(L<=l && R>=r){return mx1[rt];}
int m=l+r>>;
pushdown(l,r,rt);
if(R<=m)return query2(L,R,lson);
else if(L>m)return query2(L,R,rson);
else {
int t1=query2(L,R,lson),t2=query2(L,R,rson);
int t3=max(t1,t2);
return max(t3,min(rmx1[rt<<],m-L+)+min(lmx1[rt<<|],R-m));
}
pushup(l,r,rt);
} int main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i=;i<n;i++)cin>>a[i];
build(,n-,);
while(m--){
int opt,l,r;
cin>>opt>>l>>r;
//l++,r++;
if(opt==)update0(l,r,,n-,);
if(opt==)update1(l,r,,n-,);
if(opt==)update2(l,r,,n-,);
if(opt==)cout<<query1(l,r,,n-,)<<'\n';
if(opt==)cout<<query2(l,r,,n-,)<<'\n';
}
}
}

hdu3397区间覆盖,区间翻转,区间合并,区间求和的更多相关文章

  1. HDU 3397 区间覆盖,颠倒,合并(好题)

    http://acm.hust.edu.cn/vjudge/problem/14689 三个操作 [a,b]覆盖为0 [a,b]覆盖为1 [a,b]颠倒每项 两个查询 [a,b]间1数量 [a,b]间 ...

  2. 牛客挑战赛40 VMware和基站 set 二分 启发式合并 区间覆盖

    LINK:VMware和基站 一道 做法并不常见的题目 看起来很难写 其实set维护线段就可以解决了. 容易想到 第二个操作借用启发式合并可以得到一个很不错的复杂度 不过利用线段树维护这个东西 在区间 ...

  3. 【区间覆盖问题】uva 10020 - Minimal coverage

    可以说是区间覆盖问题的例题... Note: 区间包含+排序扫描: 要求覆盖区间[s, t]; 1.把各区间按照Left从小到大排序,如果区间1的起点大于s,则无解(因为其他区间的左起点更大):否则选 ...

  4. nyoj 12——喷水装置二——————【贪心-区间覆盖】

    喷水装置(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的 ...

  5. 洛谷P2439 [SDOI2005]阶梯教室设备利用(带权区间覆盖)

    题目背景 我们现有许多演讲要在阶梯教室中举行.每一个演讲都可以用唯一的起始和终止时间来确定,如果两个演讲时间有部分或全部重复,那么它们是无法同时在阶级教室中举行的.现在我们想要尽最大可能的利用这个教室 ...

  6. 51nod 1091 线段的重叠【贪心/区间覆盖类】

    1091 线段的重叠 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 X轴上有N条线段,每条线段包括1个起点和终点.线段的重叠是这样来算的,[10 2 ...

  7. Cleaning Shifts(区间覆盖)

    /* http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?pid=1019&ojid=1&cid=10 题目: 给定一个时 ...

  8. [LeetCode] Merge Intervals 合并区间

    Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8, ...

  9. HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)

    http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ...

随机推荐

  1. mac burp suite https证书安装

    1. 下载burp suite 2.安装,设置并代理上 3. 打开http://burp并且下载证书 4. 点击打开选择始终信任并且导出桌面 5. 火狐打开设置至证书一栏[证书机构]导入切信任 6.大 ...

  2. Hibernate_事务管理

    今天学习Hibernate,发现当我在执行下面操作时,不会对数据库产生任何效果,就是说Customer对象并不会保存到数据库中 Session session = HibernateUtils.ope ...

  3. jenkins ansible 附zabbix_agent批量安装示例

    插件:Ansible plugin 一.ansible ad-hoc command 二.ansible-playbook 批量部署zabbix-agent示例: playbook 目录及文件组成 [ ...

  4. nginx的负载均衡配置,常用策略

    场景:nginx是一款非常优秀的负载均衡服务器,小巧而且性能强悍,中小型企业的首选. 下面介绍nginx的负载均衡的几种常见的配置以及优缺点 第一种:轮询(默认) 优点:实现简单 缺点:不考虑每台服务 ...

  5. JS控制CSS3,添加浏览器兼容前缀

    不同浏览器对于有些css3属性名字定义的时候,会带上特有的前缀,所以在css编写的时候,经常会一个属性写多个不同的前缀进行兼容.比如: div { transform: rotate(30deg); ...

  6. Spring的单例实现原理-登记式单例

    单例模式有饿汉模式.懒汉模式.静态内部类.枚举等方式实现,但由于以上模式的构造方法是私有的,不可继承,Spring为实现单例类可继承,使用的是单例注册表的方式(登记式单例). 什么是单例注册表呢, 登 ...

  7. 02-MySQL的安装和配置

    1. 软件和环境 注:安装MySQL数据库的操作系统必须保证有.NET环境和VC运行库的支持.    下载地址:百度云网盘链接 2. MySQL服务器安装详细步骤 (1). 选择安装类型 这里我们选择 ...

  8. Java Web 自定义标签

    1.   自定义标签 由于在JSP页面中直接嵌入Java代码会导致页面开起来非常混乱,不方便和美工等配合工作,为此,JSP提供了自定义标签技术,可以代替直接嵌入Java代码的方式提供动态逻辑,但自定义 ...

  9. 一个单js文件也可以运行vue

    新建一个hello.html文件,输入以下内容: <html> <head> <title></title> <script src=" ...

  10. 夏令时(DST)测试

    夏令时测试是比较小众的测试,主要针对在有夏令时的国家使用的软件,如果你接触到了这方面的测试,说明你在挣国外的钱:).   话不多说,先来介绍下什么是夏令时:   夏时制,夏时令(Daylight Sa ...