HDU 3911 Black And White (线段树区间合并 + lazy标记)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3911
给你n个数0和1,m个操作:
0操作 输出l到r之间最长的连续1的个数
1操作 将l到r之间的0变1,1变0
区间合并的模版题,结构体中的lsum1表示从此区间最左端开始连续1的个数,rsum1表示从此区间最右端开始连续1的个数,sum1表示此区间连续1的个数最长是多少。lsum0,rsum0,sum0也是如此。每一次1的操作将区间内lazy标记与1异或一次,异或两次就说明操作抵消了。然后就是细心点就好了。
- #include <iostream>
- #include <cstring>
- #include <cstdio>
- using namespace std;
- const int MAXN = 1e5 + ;
- struct SegTree {
- int l , r , lazy;
- int lsum1 , rsum1 , sum1;
- int lsum0 , rsum0 , sum0;
- }T[MAXN << ];
- int a[MAXN];
- void Pushdown(int p) {
- if(T[p].lazy) {
- int ls = p << , rs = (p << )|;
- T[ls].lazy ^= T[p].lazy;
- T[rs].lazy ^= T[p].lazy;
- int temp = T[ls].lsum1;
- T[ls].lsum1 = T[ls].lsum0;
- T[ls].lsum0 = temp;
- temp = T[ls].rsum1;
- T[ls].rsum1 = T[ls].rsum0;
- T[ls].rsum0 = temp;
- temp = T[ls].sum1;
- T[ls].sum1 = T[ls].sum0;
- T[ls].sum0 = temp;
- temp = T[rs].lsum1;
- T[rs].lsum1 = T[rs].lsum0;
- T[rs].lsum0 = temp;
- temp = T[rs].rsum1;
- T[rs].rsum1 = T[rs].rsum0;
- T[rs].rsum0 = temp;
- temp = T[rs].sum1;
- T[rs].sum1 = T[rs].sum0;
- T[rs].sum0 = temp;
- T[p].lazy = ;
- }
- }
- void Pushup(int p) {
- T[p].lsum1 = T[p << ].lsum1 , T[p].lsum0 = T[p << ].lsum0;
- T[p].rsum1 = T[(p << )|].rsum1 , T[p].rsum0 = T[(p << )|].rsum0;
- if(T[p].lsum1 == T[p << ].r - T[p << ].l + )
- T[p].lsum1 += T[(p << )|].lsum1;
- if(T[p].rsum1 == T[(p << )|].r - T[(p << )|].l + )
- T[p].rsum1 += T[p << ].rsum1;
- if(T[p].lsum0 == T[p << ].r - T[p << ].l + )
- T[p].lsum0 += T[(p << )|].lsum0;
- if(T[p].rsum0 == T[(p << )|].r - T[(p << )|].l + )
- T[p].rsum0 += T[p << ].rsum0;
- T[p].sum1 = max(T[p << ].sum1 , max(T[(p << )|].sum1 , T[p << ].rsum1 + T[(p << )|].lsum1));
- T[p].sum0 = max(T[p << ].sum0 , max(T[(p << )|].sum0 , T[p << ].rsum0 + T[(p << )|].lsum0));
- }
- void build(int p , int l , int r) {
- int mid = (l + r) >> ;
- T[p].lazy = ;
- T[p].l = l , T[p].r = r;
- if(l == r) {
- scanf("%d" , a + l);
- T[p].sum1 = T[p].lsum1 = T[p].rsum1 = a[l] ? : ;
- T[p].sum0 = T[p].lsum0 = T[p].rsum0 = a[l] ? : ;
- return ;
- }
- build(p << , l , mid);
- build((p << )| , mid + , r);
- Pushup(p);
- }
- void updata(int p , int l , int r , int flag) {
- int mid = (T[p].l + T[p].r) >> ;
- if(T[p].l == l && T[p].r == r) {
- T[p].lazy ^= flag;
- int temp = T[p].lsum1;
- T[p].lsum1 = T[p].lsum0;
- T[p].lsum0 = temp;
- temp = T[p].rsum1;
- T[p].rsum1 = T[p].rsum0;
- T[p].rsum0 = temp;
- temp = T[p].sum1;
- T[p].sum1 = T[p].sum0;
- T[p].sum0 = temp;
- return ;
- }
- Pushdown(p);
- if(r <= mid) {
- updata(p << , l , r , flag);
- }
- else if(l > mid) {
- updata((p << )| , l , r , flag);
- }
- else {
- updata(p << , l , mid , flag);
- updata((p << )| , mid + , r , flag);
- }
- Pushup(p);
- }
- int query(int p , int l , int r) {
- int mid = (T[p].l + T[p].r) >> ;
- if(T[p].l == l && T[p].r == r) {
- return T[p].sum1;
- }
- Pushdown(p);
- if(r <= mid) {
- return query(p << , l , r);
- }
- else if(l > mid) {
- return query((p << )| , l , r);
- }
- else {
- return max( min(T[p << ].rsum1 , mid - l + )+min(T[(p << )|].lsum1 , r - mid) , //mid在l和r之间
- max( query(p << , l , mid) , query((p << )| , mid + , r)) );
- }
- }
- int main()
- {
- int n , m , choose , u , v;
- while(~scanf("%d" , &n)) {
- build( , , n);
- scanf("%d" , &m);
- while(m--) {
- scanf("%d %d %d" , &choose , &u , &v);
- if(choose) {
- updata( , u , v , );
- }
- else {
- printf("%d\n" , query( , u , v));
- }
- }
- }
- return ;
- }
HDU 3911 Black And White (线段树区间合并 + lazy标记)的更多相关文章
- HDU 4553 约会安排(线段树区间合并+双重标记)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 题目大意:就是有三种操作: ①DS x,安排一段长度为x的空闲时间跟屌丝一起,输出这段时间的起点 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- hdu 3911 Black And White(线段树)
题目连接:hdu 3911 Black And White 题目大意:给定一个序列,然后有M次操作: 0 l r:表示询问l,r中最大连续1的个数 1 l r:表示将l,r区间上的数取反 解题思路:线 ...
- HDU 3911 Black and White (线段树,区间翻转)
[题目地址] vjudge HDU [题目大意] 海滩上有一堆石头. 石头的颜色是白色或黑色. 小肥羊拥有魔术刷,她可以改变连续石的颜色,从黑变白,从白变黑. 小肥羊非常喜欢黑色,因此她想知道范围 ...
- HDU 1540 Tunnel Warfare(线段树+区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目大意:抗日战争期间进行地道战,存在n个村庄用地道连接,输入D表示破坏某个村庄(摧毁与其相连的地道, 包 ...
- HDU - 1540 Tunnel Warfare(线段树区间合并)
https://cn.vjudge.net/problem/HDU-1540 题意 D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 分析 线段树的区间内,我 ...
- hdu 1540 Tunnel Warfare (线段树 区间合并)
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- (简单) HDU 3397 Sequence operation,线段树+区间合并。
Problem Description lxhgww got a sequence contains n characters which are all '0's or '1's. We have ...
- hdu 3911 Black And White (线段树 区间合并)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...
随机推荐
- 利用dns解析来实现网站的负载均衡
当网站的访问量大了就会考虑负载均衡,这也是每一个架构师的基本功了,其基本地位就相当于相声里的说学逗唱,活好不好就看这个了 :) 传统的负载均衡思路是单点的,不管你是硬件的还是软件的基本都是这样的原理 ...
- UVA 10537 The Toll! Revisited uva1027 Toll(最短路+数学坑)
前者之所以叫加强版,就是把uva1027改编了,附加上打印路径罢了. 03年的final题哦!!虽然是水题,但不是我这个只会做图论题的跛子能轻易尝试的——因为有个数学坑. 题意:运送x个货物从a-&g ...
- UVA 11806 Cheerleaders (容斥原理)
题意 一个n*m的区域内,放k个啦啦队员,第一行,最后一行,第一列,最后一列一定要放,一共有多少种方法. 思路 设A1表示第一行放,A2表示最后一行放,A3表示第一列放,A4表示最后一列放,则要求|A ...
- NavieBayes中的多项式与伯努力模型
1文本分类过程 例如文档:Good good study Day day up可以用一个文本特征向量来表示,x=(Good, good, study, Day, day , up).在文本分类中,假设 ...
- QuartZ Cron表达式在java定时框架中的应用
CronTrigger CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔,复发的发射工作的时间表. CronT ...
- Mac下配置PHP+Apache+phpMyAdmin+MySql远程链接
最近的项目是微信公众号平台的开发,微信官方给出的Demo是PHP的,发现大部分的学习资料也是PHP,那好吧,放弃Java,来段儿PHP吧 下面说说Mac下搭建PHP环境 数据库:MySQL-5.6.2 ...
- 【JSP】三种弹出对话框的用法实例
对话框有三种 1:只是提醒,不能对脚本产生任何改变: 2:一般用于确认,返回 true 或者 false ,所以可以轻松用于 if...else...判断 3: 一个带输入的对话框,可以返回用户填入的 ...
- vs 2005中解决找不到模板项
开始-->所有程序-->Microsoft Visual Studio 2005-->Visual Studio Tools-->Visual Studio 2005 Comm ...
- CKEditor如何统计文字数量
今天在修改v5后台的比赛系统时,发现文本框需要限制输入字数.我们这个系统用的是3.6.3版本的,前台代码是这样的 <script> //编辑器 CKEDITOR.replace('matc ...
- android view的setVisibility方法值的意思
android view的setVisibility方法值的意思 有三个值 visibility One of VISIBLE, INVISIBLE, or GONE. 常量值为0,意思是可见的 常 ...