题目连接: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. windows phone 墓碑化(9)

    原文:windows phone 墓碑化(9) 几个术语的理解: 名称 说明 ;        App ap = (App)Application.Current;        // 构造函数    ...

  2. cocos2d-x 音乐/音效设置

    cocos2d-x 游戏中声音 有两种 一种是背景音乐一种是音效 载入音乐 或者音效的时候 我们须要先缓存声音 #include "SimpleAudioEngine.h" usi ...

  3. hdu2089不要62(数位dp)

    #include <stdio.h> #include <string.h> ][]; ]; /* dp[i][0] 不含62,4 dp[i][1] 2开头 dp[i][2] ...

  4. QQ旅程server分析01-网关server

    网关server网络进程: s1.连接网关管理器 s2.上报自身信息给网关管理器 s3.从网关管理器获取自己的管理信息 *s4.依照管理信息预分配好须要的资源 s5.网关server打开client监 ...

  5. Java EE (4) -- Java EE 6 Java Persistence API Developer Certified Expert(1z0-898)

    Overview of the Java Persistence API Describe the basics of Object Relational Mapping (ORM) Define t ...

  6. java输入输出高速

    头文件: import java.io.*; 定义: BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); ...

  7. twisted是python实现的基于事件驱动的异步网络通信构架。

    网:https://twistedmatrix.com/trac/ http://www.cnblogs.com/wy-wangyan/p/5252271.html What is Twisted? ...

  8. Oracle 11G CRUD操作监控单个表

    前言:    线上oracle数据库有张表的数据有些乱,依据应用db的log和应用的log也没有检查出来谁改动了.所以决定把这张单表做个具体的insert.update.delete监控.一:使用数据 ...

  9. 使用 WPF 实现所见即所得HTML编辑器

    Introduction In this tip, you will learn the use of WPF webbrowser control and the use of the librar ...

  10. Java 的swing.GroupLayout布局管理器的使用方法和实例(转)

    The following builds a panel consisting of two labels in one column, followed by two textfields in t ...