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 ...
随机推荐
- Java Code Examples for javax.servlet.http.Part
http://www.programcreek.com/java-api-examples/index.php?api=javax.servlet.http.Part The following ar ...
- 通过rsync搭建一个远程备份系统(二)
Rsync+inotify实时备份数据 rsync在同步数据的时候,需要扫描所有文件后进行对比,然后进行差量传输,如果文件达到了百万或者千万级别以上是,扫描文件的时间也很长,而如果只有少量的文件变更了 ...
- map转json
if (javaObject instanceof Map) { Map<Object, Object> map = (Map<Object, Object>) javaObj ...
- 初识PHP
初识PHP 虽然是做前端的,可是平时看书.做项目都会与后端PHP相关,但却不是很了解,并经常听PHP大神说:PHP是世界上最好的语言!因此,通过这篇博文学习.总结PHP,来认识认识这个“世界上最好的语 ...
- Objective-C之字典
//字典:(关键字 值) //插入代码字太小 // NSArray *array = [NSArray array];//空数组 // NSDictionary *dict ...
- MVC过滤器之 OnActionExcuted
Controller里 [SendMessage] public Action SendSmsMessage() { var resultExtendInfo=new ResultExtendInfo ...
- lua 闭包
--匿名函数使用upvalue i保存他的计数, 闭包是一个函数加上它可以正确访问的upvalues function newCounter() return function() i = i + r ...
- ubuntu server设置时区和更新时间
ubuntu server设置时区和更新时间 今天测试时,发现时间不对,查了一下时区: data -R 结果时区是:+0000 我需要的是东八区,这儿显示不是,所以需要设置一个时区 一.运行 ...
- ubuntu下安装TexLive和Texmaker
也可以参考ubuntu14.04配置中文latex完美环境(texlive+texmaker+lyx) 设置中文字体的时候参考ubuntu 下安装 texlive 并设置 ctex 中文套装 1.首先 ...
- 《深入理解bootstrap》读书笔记:第三章 CSS布局
一. 概述一下理念 bootstrap基于H5开发.提倡移动先行(媒询声明是必须的),对浏览器支持面不是很广. 响应式图片:max-width:100% height:auto; 可以加上:.img- ...