题目连接:hdu 3911 Black And White

题目大意:给定一个序列,然后有M次操作;

  • 0 l r:表示询问l,r中最大连续1的个数
  • 1 l r:表示将l,r区间上的数取反

解题思路:线段树的一种题型,区间合并,由于有一个取反的操作,所以对于每一个节点要维护6个值,包含连续0,1最长序列的长度,左边和右边的最长连续长度。须要注意的是,假设询问的区间最大值是从R[lson] + L[rson]来到,要推断是否比长度大于r - l + 1。一開始没注意,所以WA了,上网搜了下别人的题解,发现非常多人在query里面没有pushup更新当前节点信息,这样肯定是不行的,有pushdown,肯定要在更新当前节点信息的。

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = 1e5 + 5; int N, M, a[maxn]; #define lson(x) ((x)<<1)
#define rson(x) (((x)<<1)|1)
int lc[maxn << 2], rc[maxn << 2], filp[maxn << 2];
int L[maxn << 2][2], R[maxn << 2][2], S[maxn << 2][2]; void maintain (int u) {
filp[u] ^= 1;
swap(L[u][0], L[u][1]);
swap(R[u][0], R[u][1]);
swap(S[u][0], S[u][1]);
} void pushup(int u) {
for (int i = 0; i < 2; i++) {
S[u][i] = max(max(S[lson(u)][i], S[rson(u)][i]), R[lson(u)][i] + L[rson(u)][i]);
L[u][i] = L[lson(u)][i] + (L[lson(u)][i] == rc[lson(u)] - lc[lson(u)] + 1 ? L[rson(u)][i] : 0);
R[u][i] = R[rson(u)][i] + (R[rson(u)][i] == rc[rson(u)] - lc[rson(u)] + 1 ? R[lson(u)][i] : 0);
}
} void pushdown (int u) {
if (filp[u]) {
maintain(lson(u));
maintain(rson(u));
filp[u] = 0;
}
} void build (int u, int l, int r) {
lc[u] = l;
rc[u] = r;
filp[u] = 0; if (l == r) {
int d = a[l];
L[u][d] = R[u][d] = S[u][d] = 1;
L[u][d^1] = R[u][d^1] = S[u][d^1] = 0;
return ;
} int mid = (l + r) / 2;
build(lson(u), l, mid);
build(rson(u), mid+1, r);
pushup(u);
} void modify (int u, int l, int r) {
if (l <= lc[u] && rc[u] <= r) {
maintain(u);
return;
} pushdown(u);
int mid = (lc[u] + rc[u]) / 2;
if (l <= mid)
modify(lson(u), l, r);
if (r > mid)
modify(rson(u), l, r);
pushup(u);
} int query (int u, int l, int r) {
if (l <= lc[u] && rc[u] <= r)
return S[u][1]; pushdown(u);
int mid = (lc[u] + rc[u]) / 2, ret;
if (r <= mid)
ret = query(lson(u), l, r);
else if (l > mid)
ret = query(rson(u), l, r);
else {
int ll = query(lson(u), l, r);
int rr = query(rson(u), l, r); int a = min(L[rson(u)][1], r - mid);
int b = min(R[lson(u)][1], mid - l + 1); ret = max( max(ll, rr), a + b);
}
pushup(u);
return ret;
} int main () {
int x, l, r; while (scanf("%d", &N) == 1) {
for (int i = 1; i <= N; i++)
scanf("%d", &a[i]);
build (1, 1, N); scanf("%d", &M);
while (M--) {
scanf("%d%d%d", &x, &l, &r);
if (x)
modify(1, l, r);
else
printf("%d\n", query(1, l, r));
}
}
return 0;
}

hdu 3911 Black And White(线段树)的更多相关文章

  1. HDU 3911 Black and White (线段树,区间翻转)

      [题目地址] vjudge HDU [题目大意] 海滩上有一堆石头. 石头的颜色是白色或黑色. 小肥羊拥有魔术刷,她可以改变连续石的颜色,从黑变白,从白变黑. 小肥羊非常喜欢黑色,因此她想知道范围 ...

  2. 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之间 ...

  3. HDU 3911 Black And White 分段树 题解

    Problem Description There are a bunch of stones on the beach; Stone color is white or black. Little ...

  4. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  5. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  6. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  7. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  8. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  9. HDU.1689 Just a Hook (线段树 区间替换 区间总和)

    HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...

随机推荐

  1. mysql安装注意

    mysql安装教程,网上到处都有,我这里就不细说了. 但是有一点要注意,安装完之后,点击MySql 5.5 Command Line Client时,有可能出现一闪而过,打不开mysql的情况: 首先 ...

  2. Codeforces Round#308

    A题,看样例就知道要求什么,   水过去 #include <stdio.h> #include <string.h> #include <stdlib.h> #i ...

  3. C#遍历FTP文件夹/下载

    原文链接:http://blog.csdn.net/ou8811/article/details/5295780 整个程序大致可以分为2个部分,第一部分是实现单个文件下载的方法 [c-sharp] v ...

  4. SQLServer2014新功能

    随机存取存储器 OLTP:提供了内置在芯 SQL Server 数据库内存 OLTP 特征,为了显著提高事务数据库应用程序的速度和吞吐量.随机存取存储器 OLTP 它是包含在 SQL Server 2 ...

  5. extjs的相关属性

    通用属性: labelSeparator:''//表示fieldLabel后不会显示冒号":" readOnly:true//仅仅读 focusCls: 'txtHalfInput ...

  6. java战斗系列-战斗MAVENPW结构

     实战中MAVEN私服的搭建 利用maven来管理项目的构建,报告和文档已经成为了我们如今的共识,不论什么开源软件基本都在使用,当然我们如今的大部分公司也基本都在使用,我把曾经使用maven的一些经 ...

  7. [转载][NAS] 使用win8的“存储池”功能~

    之前自己用DQ77KB搭建一个小存储系统(帖子链接:http://www.chiphell.com/thread-567753-1-1.html),一直使用intel主板带的软RAID功能构建RAID ...

  8. twrp gui/actions.cpp 中的功能实现 tw_action ,tw_action_param ,第二章

    继续分析 twrp ui.xml中的相关内容,以<page name="reboot">为讲解内容 <object type="button" ...

  9. kernel 于ioctl申请书

    ioctl经营无纸装置频繁使用的类型.同时这是一个非常实用的方法进程调试. 这里正在进行wdt该文章继续 static long at91_wdt_ioctl(struct file *file, u ...

  10. Autofac 入门

    Autofac 入门文档 原文链接:http://docs.autofac.org/en/latest/getting-started/index.html 在程序中使用Autofac的基本模式是: ...