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 ...
随机推荐
- PhyLab2.0需求与功能分析改进文档(NABCD)
PhyLab1.0需求规格说明文档 1. 概述 1.1 项目概述 软剑攻城队小组于2015学年开发了PhyLab物理实验网站,一经发布好评如潮.网站的核心功能是提供预习报告和自动数据处理,而后加入了论 ...
- DNS(二)之bind的视图功能
bind视图工作原理 在我国目前的网络环境下面,多个运营商并存,运营商之间的存在一定的网络互通问题,如果把来自不同的运营商或者地域的所有用户通过简单的A记录分配到一个机房,那么就存在部分网民访问延时大 ...
- Altium Designer 15 --- PCB 3D View
press 3 key to swith to 3D view, and press shift key and dont' loose your grip, hold the right mouse ...
- JavaWeb---总结(六)Servlet开发(一)
一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...
- edmx代码分析
http://www.cnblogs.com/FoundationSoft/archive/2011/01/08/1930479.html 本文分析Entity Framework从数据库自动生成的模 ...
- 表x有 一列 ,程序每次生成id的时候都先从这里获取最大值再加1,初始值是A0001,然后到A9999的时候则是到B0001 共5位
drop table x gocreate table x(id varchar(10))--insert into x values('A001')gowith a as (select ISNUL ...
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
一.MD(d).MT(d)编译选项的区别 1.编译选项的位置 以VS2005为例,这样子打开: 1) 打开项目的Property Pages对话框 2) 点击左侧C/C ...
- ubuntu亮度调节失效
ctrl+alt+T 打开终端 输入下面的指令 sudo touch /usr/share/X11/xorg.conf.d/20-intel.conf 2 再输入下面的指令: sudo gedit / ...
- Jasper(物联网网络支撑平台公司)的技术为什么这么牛逼?
Jasper在这个行业积累了十几年,合作的运营商超过30个,合作的行业大咖包括了通用.空客.宝马.特斯拉等几千个行业龙头,还是有很多积累下来的优势的. 一是,Jasper通过积累下来的行业应用经验,针 ...
- TeXmacs - 所见即所得 - 专业排版软件
所见即所得,支持中文,很好用, 容易奔溃,奔溃进入不了程序时,删除文件夹 C:\Users\Perelman\AppData\Roaming\TeXmacs