线段树的应用,很不错的一道题目。结点属性包括:
(1)n1:1的个数;
(2)c1:连续1的最大个数;
(3)c0:连续0的最大个数;
(4)lc1/lc0:从区间左边开始,连续1/0的最大个数;
(5)rc1/rc0:从区间右边开始,连续1/0的最大个数;
(6)set:置区间为0/1的标记;
(7)flip:0->1, 1->0的标记。
采用延迟更新。每当更新set时,flip就置为false;每当更新flip时,其实就是c1/c0, lc1/lc0, rc1/rc0的交换。
对于询问最长连续1,共包括3种情况:左子树的最长连续1,右子树的最长连续1,以及左子树rc1+右子树lc1(注意有效范围区间)。

 /* 3397 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std; #define MAXN 100005
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct {
int set;
int n1;
int c1, c0;
int lc1, lc0, rc1, rc0;
bool flip;
} node_t; node_t nd[MAXN<<];
int t, n, m, x;
int op; void maintance_set(int op, int len, int rt) {
nd[rt].set = op;
nd[rt].flip = false;
if (op) {
nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = len;
nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = ;
} else {
nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = ;
nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = len;
}
} void maintance_flip(int len, int rt) {
if (nd[rt].set >= )
nd[rt].set = !nd[rt].set;
else
nd[rt].flip = !nd[rt].flip;
nd[rt].n1 = len-nd[rt].n1;
swap(nd[rt].c0, nd[rt].c1);
swap(nd[rt].lc0, nd[rt].lc1);
swap(nd[rt].rc0, nd[rt].rc1);
} void PushUp(int l, int r, int rt) {
int lb = rt<<;
int rb = rt<<|;
int mid = (l+r)>>; // update the number of 1
nd[rt].n1 = nd[lb].n1 + nd[rb].n1;
// update the longest continuous 1 and 0 in string
nd[rt].c1 = max(
max(nd[lb].c1, nd[rb].c1),
nd[lb].rc1 + nd[rb].lc1
);
nd[rt].c0 = max(
max(nd[lb].c0, nd[rb].c0),
nd[lb].rc0 + nd[rb].lc0
);
// update the longest continuous 1/0 from left
nd[rt].lc1 = nd[lb].lc1;
nd[rt].lc0 = nd[lb].lc0;
if (nd[lb].lc1 == mid-l+)
nd[rt].lc1 += nd[rb].lc1;
if (nd[lb].lc0 == mid-l+)
nd[rt].lc0 += nd[rb].lc0;
// update the longest continuous 1/0 from right
nd[rt].rc1 = nd[rb].rc1;
nd[rt].rc0 = nd[rb].rc0;
if (nd[rb].rc1 == r-mid)
nd[rt].rc1 += nd[lb].rc1;
if (nd[rb].rc0 == r-mid)
nd[rt].rc0 += nd[lb].rc0;
} void PushDown(int l, int r, int rt) {
int lb = rt<<;
int rb = rt<<|;
int mid = (l+r)>>; if (nd[rt].set >= ) {
// maintance_set lson & rson
maintance_set(nd[rt].set, mid-l+, lb);
maintance_set(nd[rt].set, r-mid, rb);
nd[rt].set = -;
}
if (nd[rt].flip) {
// maintance_flip lson & rson
maintance_flip(mid-l+, lb);
maintance_flip(r-mid, rb);
nd[rt].flip = false;
}
} void build(int l, int r, int rt) {
nd[rt].set = -;
nd[rt].flip = false;
if (l == r) {
scanf("%d", &x);
nd[rt].n1 = nd[rt].c1 = nd[rt].lc1 = nd[rt].rc1 = x;
nd[rt].c0 = nd[rt].lc0 = nd[rt].rc0 = !x;
return ;
}
int mid = (l+r)>>;
build(lson);
build(rson);
PushUp(l, r, rt);
} // update to set [L, R] to op
void update1(int L, int R, int l, int r, int rt) {
if (L<=l && R>=r) {
maintance_set(op, r-l+, rt);
return ;
}
int mid = (l+r)>>;
PushDown(l, r, rt);
if (L <= mid)
update1(L, R, lson);
if (R > mid)
update1(L, R, rson);
PushUp(l, r, rt);
} // update to flip [L, R] one
void update2(int L, int R, int l, int r, int rt) {
if (L<=l && R>=r) {
maintance_flip(r-l+, rt);
return ;
}
int mid = (l+r)>>;
PushDown(l, r, rt);
if (L <= mid)
update2(L, R, lson);
if (R > mid)
update2(L, R, rson);
PushUp(l, r, rt);
} // query the sum of 1 in [L, R]
int query3(int L, int R, int l, int r, int rt) {
if (L<=l && R>=r)
return nd[rt].n1;
int mid = (l+r)>>;
PushDown(l, r, rt);
int ret = ;
if (L <= mid)
ret += query3(L, R, lson);
if (R > mid)
ret += query3(L, R, rson);
return ret;
} // query the longest continous 1 in [L, R]
int query4(int L, int R, int l, int r, int rt) {
if (L<=l && R>=r)
return nd[rt].c1;
int mid = (l+r)>>;
PushDown(l, r, rt);
int ret;
if (L > mid) {
return query4(L, R, rson);
} else if (R <= mid) {
return query4(L, R, lson);
} else {
ret = max(
query4(L, R, lson),
query4(L, R, rson)
);
int rc1 = nd[rt<<].rc1;
int lc1 = nd[rt<<|].lc1;
if (rc1 > mid-L+)
rc1 = mid-L+;
if (lc1 > R-mid)
lc1 = R-mid;
ret = max(
rc1 + lc1,
ret
);
}
return ret;
} int main() {
int i, j, k;
int a, b; #ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif scanf("%d", &t);
while (t--) {
scanf("%d %d", &n, &m);
build(, n, );
while (m--) {
scanf("%d %d %d", &op, &a, &b);
++a;
++b;
if (op == ) {
update1(a, b, , n, );
} else if (op == ) {
update1(a, b, , n, );
} else if (op == ) {
update2(a, b, , n, );
} else if (op == ) {
k = query3(a, b, , n, );
printf("%d\n", k);
} else {
k = query4(a, b, , n, );
printf("%d\n", k);
}
}
} return ;
}

【HDOJ】3397 Sequence operation的更多相关文章

  1. HDU 3397 Sequence operation(线段树)

    HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...

  2. 【arc071f】Infinite Sequence(动态规划)

    [arc071f]Infinite Sequence(动态规划) 题面 atcoder 洛谷 题解 不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等. 设\(f[i]\)表示\([ ...

  3. 【arc074e】RGB Sequence(动态规划)

    [arc074e]RGB Sequence(动态规划) 题面 atcoder 洛谷 翻译见洛谷 题解 直接考虑暴力\(dp\),设\(f[i][j][k][l]\)表示当前考虑到第\(i\)位,最后一 ...

  4. 【BZOJ1367】[Baltic2004]sequence 左偏树

    [BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...

  5. 【BZOJ3043】IncDec Sequence 乱搞

    [BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...

  6. hdu 3397 Sequence operation(很有意思的线段树题)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. 【HDOJ】5063 Operation the Sequence

    #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 100005 #defin ...

  8. 【线段树】HDU 3397 Sequence operation 区间合并

    操作 Change operations: 0 a b change all characters into '0's in [a , b] 1 a b change all characters i ...

  9. 【HDOJ】2062 Subset sequence

    这道题目非常好,饶了点儿圈子.我的思路是,先按照组排列.例如,1            2           31 2         2 1        3 11 2 3      2 1 3  ...

随机推荐

  1. 详解android:scaleType属性

    详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262    http://juliaailse. ...

  2. C#有关 字符串方法的使用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  3. CSS 尺寸 (Dimension)

    CSS 尺寸 (Dimension) 属性允许你控制元素的高度和宽度.同样,它允许你增加行间距. 更多实例 设置元素的高度 这个例子演示了如何设置不同元素的高度. 使用百分比设置图像的高度 这个例子演 ...

  4. CSS Outlines

    轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用. 轮廓(outline)属性指定了样式,颜色和外边框的宽度. 轮廓(outline)实例 在元素周围画线本例演 ...

  5. 配置wamp开发环境【2】 配置wamp开发环境之mysql的配置

    此前我已经将wamp配置的Apache.PHP.phpmyadmin全部配置完成,以上三种配置参照 配置wamp开发环境 下面我们来看看mysql的配置,这里用的是mysql5.5.20,下载地址: ...

  6. 前端开发构建工具gulp的安装使用

    曾几何时还在使用grunt作为前端的构建工具,直到有一天同事向我推荐了gulp,在这里博主将不讨论gulp与grunt各自优势的比较,只为大家介绍gulp如何安装和使用. Gulp 是用 nodejs ...

  7. 网络编程(学习整理)---3--(Udp)FeiQ实现广播消息群发

    1.广播群发消息: 这里使用的任然是UDP协议,使用方法还是比较简单的! 我就记录一下需要注意的一些地方(笔记): (1)这里是在局域网内,借用FeiQ聊天软件,编写一段程序,实现对局域网内的每一个登 ...

  8. STP根交换机,指定端口,根端口,阻塞端口

    STP判断各交换机端口(指定端口:DP;根端口:RP;阻塞端口:AP) 判断步骤: 1.选举根交换机: 判断对象:所有运行STP协议的交换机中选出一个; 判断依据:交换机中选择网桥ID值(交换机优先级 ...

  9. P次方数 英雄会 csdn 高校俱乐部

    题目: 一个整数N,|N| >= 2, 如果存在整数x,使得N = x * x * x... (p个x相乘) =x^p,则称N是p次方数,给定32位内的整数N,求最大的P.例如N=5,输出1,N ...

  10. Codeforces 553C Love Triangles(图论)

    Solution: 比较好的图论的题. 要做这一题,首先要分析love关系和hate关系中,love关系具有传递性.更关键的一点,hate关系是不能成奇环的. 看到没有奇环很自然想到二分图的特性. 那 ...