题目: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 线段树区间合并、异或取反操作的更多相关文章

  1. HDU 3911 线段树区间合并

    北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #includ ...

  2. hdu 3308(线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. hdu 1806(线段树区间合并)

    Frequent values Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. hdu 3308 线段树 区间合并+单点更新+区间查询

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 3911 Black And White (线段树 区间合并)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...

  6. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  7. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

  8. HDU 3308 (线段树区间合并)

    http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作  : 1 修改 单点  a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...

  9. HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举

    HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...

随机推荐

  1. 安卓开发30:AsyncTask的用法

    http://blog.csdn.net/initphp/article/details/10392093 安卓开发笔记系列(43)  在开发Android应用时必须遵守单线程模型的原则: Andro ...

  2. 初识JSLint及建议JS编码风格

    可能都或多或少的知道JSLint是一个JavaScript的代码质量工具,一个JavaScript语法检查器和校验器,它能分析JavaScript问题并报告它包含的缺点. 被发现的问题往往是语法错误, ...

  3. 01C语言基础知识

    C语言知识要点总结 1在C语言中,关系运算的结果为“真”,就返回1,"假"就返回0 printf("input value is %d" , 5 > 4) ...

  4. import_site

    http://kfd.me/ https://google.kfd.me/webhp?newwindow=1&safe=active http://googlebridge.com/searc ...

  5. su su- sudo的区别

    linux su命令参数及用法详解(linux切换用户命令) su的作用是变更为其它使用者的身份,超级用户除外,需要键入该使用者的密码   linux su 命令 建议大家切换用户的时候 使用 su ...

  6. 一个C#解决方案中各文件夹存放了些什么

    在VS2015中"生成"(Build)的过程: Source Code(.cs) -> Compile -> Object File(intermediate file ...

  7. 【浅谈html5 响应式布局之自动适应屏幕宽度】

    允许网页宽度自动调整 “自适应网页设计”到底是怎么做到的?其实并不难. 首先,在网页代码的头部,加入一行viewport元标签. <meta name=”viewport” content=”w ...

  8. CentOS7安装Nginx并部署

    服务器IP是192.168.36.136 1.直接yum install nginx即可 2.主配置文件是/etc/nginx/下的nginx.conf,另外一个是/etc/nginx/conf.d/ ...

  9. python 占位符 %s Format

    1.百分号方式 %[(name)][flags][width].[precision]typecode (name)      可选,用于选择指定的key flags          可选,可供选择 ...

  10. editplus的配置和使用

    editplus以及其他所有软件的 "页" 是一个什么概念? 所谓 页 : 是指 当前 你看到的 "客户区" client 的区域大小. 如果窗口越小, 那么你 ...