HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911
线段树区间合并的题目,解释一下代码中声明数组的作用:
m1是区间内连续1的最长长度,m0是区间内连续0的最长长度,l1是从区间左端开始连续1的长度,r1是从区间右端开始连续1的长度,l0是从区间左端开始连续0的长度,r0是从区间右端开始连续0的长度,lazy标记该区间是否进行异或操作。
之所以要同时保存1的连续长度和0的连续长度,是因为这道题设计取反操作,所以取反是,只需将对应的0、1长度调换一下就可以了
#include<stdio.h>
#include<algorithm>
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
#define maxn 111111
using namespace std;
int m1[maxn*],m0[maxn*],l1[maxn*],r1[maxn*],l0[maxn*],r0[maxn*],lazy[maxn*];
void change(int rt){
swap(m1[rt],m0[rt]);
swap(l1[rt],l0[rt]);
swap(r1[rt],r0[rt]);
}
void pushup(int l,int r,int rt){
int m = (l+r)/;
//左边的长度等于左子区间左边的长度,右边的长度等于右子区间右边的长度,下同
l1[rt] = l1[rt*];
r1[rt] = r1[rt*+]; l0[rt] = l0[rt*];
r0[rt] = r0[rt*+];
//左边的长度等于区间左半长,则加上右子区间左边的长度,下同
if(l1[rt] == m-l+)
l1[rt] += l1[rt*+];
if(r1[rt] == r-m)
r1[rt] += r1[rt*]; if(l0[rt] == m-l+)
l0[rt] += l0[rt*+];
if(r0[rt] == r-m)
r0[rt] += r0[rt*];
//最大的长度为左右子区间最大长度的最大值,与该区间中间的长度取最值
m1[rt] = max(r1[rt*]+l1[rt*+],max(m1[rt*],m1[rt*+]));
m0[rt] = max(r0[rt*]+l0[rt*+],max(m0[rt*],m0[rt*+]));
}
void pushdown(int l,int r,int rt){
if(lazy[rt]){
lazy[rt*] ^= ;
lazy[rt*+] ^= ;
lazy[rt] = ;
change(rt*);
change(rt*+);
}
}
void build(int l,int r,int rt){
m1[rt] = m0[rt] = l1[rt] = r1[rt] = l0[rt] = r0[rt] = lazy[rt] = ;;
if(l == r){
scanf("%d",&m1[rt]);
if(m1[rt] == )
l1[rt] = r1[rt] = ;
else
l0[rt] = r0[rt] = m0[rt] = ;
return;
}
int m = (l+r)/;
build(lson);
build(rson);
pushup(l,r,rt);
}
void update(int l,int r,int rt,int a,int b){
if(a<=l && b>=r){
lazy[rt] ^= ;
change(rt);
return;
}
pushdown(l,r,rt);
int m = (l+r)/;
if(a <= m)
update(lson,a,b);
if(b > m)
update(rson,a,b);
pushup(l,r,rt);
}
int query(int l,int r,int rt,int a,int b){
if(a<=l && b>=r){
return m1[rt];
}
pushdown(l,r,rt);
int m = (l+r)/;
if(b <= m)
return query(lson,a,b);
if(a > m)
return query(rson,a,b);
int t1 = query(lson,a,b);
int t2 = query(rson,a,b);
//最值在左半区间、右半区间、以及中间的长度里去,其中中间的长度不能大于查询长度的边界
return max(max(t1,t2),min(m-a+,r1[rt*])+min(b-m,l1[rt*+]));
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
build(,n,);
int m;
scanf("%d",&m);
int x,a,b;
while(m--){
scanf("%d%d%d",&x,&a,&b);
if(x == ){
printf("%d\n",query(,n,,a,b));
}else{
update(,n,,a,b);
}
}
}
return ;
}
HDU 3911 线段树区间合并、异或取反操作的更多相关文章
- HDU 3911 线段树区间合并
北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #includ ...
- hdu 3308(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 1806(线段树区间合并)
Frequent values Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- hdu 3308 线段树 区间合并+单点更新+区间查询
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 3911 Black And White (线段树 区间合并)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举
HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...
随机推荐
- 高性能JavaScript笔记一(加载和执行、数据访问、DOM编程)
写在前面 好的书,可能你第一遍并不能领会里面的精魂,当再次细细品评的时候,发现领悟的又是一层新的含义 (这段时间,工作上也不会像从前一样做起来毫不费力,开始有了新的挑战,现在的老大让我既佩服又嫉妒,但 ...
- js实现身份证号码验证
/*根据[中华人民共和国国家标准 GB 11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数 ...
- w3m常用快捷键
H 显示帮助 q 退出,会有提示的 j,k,l,h 移动光标 J/K 向下/向上滚屏 T 打开一个新标签页 Esc-t 打开所有标签页,供你选择,使用jk来上下移动 U ...
- WinForm------给GridControl添加搜索功能
//按钮点击事件 private void Btn_Search_Click(object sender, EventArgs e) { //获取编辑框的值 string text = this.te ...
- squid代理服务器配置详解
root@proxy squid]# cat squid.conf## Recommended minimum configuration:#visible_hostname www.jd.com # ...
- 10月21日上午MySQL数据库学习内容复习
1.创建数据库create database 数据库名称删除数据库drop database 数据库名称 2.创建表create table 表名(列名 类型(长度) 自增长 主键 非空,)自增长:a ...
- ecshop Admin后台删除(Ajxa删除,无跳转连接)
关联文件Admin/goods.php?act=trash, Admin/js/listtable.js html代码 <a href="javascript:;" ...
- js搜索输入关键词
function getInput(val,a){ var id = 'ser-key'; if(a=='focus'){ document.getElementById(id).value=''; ...
- Session的SqlServer模式的配置
很多时候,由于各种莫名其妙的原因,会导致session丢失.不过ASP.NET还允许将会话数据存储到一个数据库服务器中,方法是将mode属性变成SqlServer. 在这种情况下,ASP.NET尝试将 ...
- setTimeout 导致的浏览器假死
问题 前几天,同事遇到一个浏览器假死的问题.就是浏览器在响应一个请求的时候,就突然不响应时间,进入假死状态,Cup也飙升到100%. 但是这个问题只出现在IE浏览器,chrome和Firefox等 ...