【HDOJ】3397 Sequence operation
线段树的应用,很不错的一道题目。结点属性包括:
(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的更多相关文章
- 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变 ...
- 【arc071f】Infinite Sequence(动态规划)
[arc071f]Infinite Sequence(动态规划) 题面 atcoder 洛谷 题解 不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等. 设\(f[i]\)表示\([ ...
- 【arc074e】RGB Sequence(动态规划)
[arc074e]RGB Sequence(动态规划) 题面 atcoder 洛谷 翻译见洛谷 题解 直接考虑暴力\(dp\),设\(f[i][j][k][l]\)表示当前考虑到第\(i\)位,最后一 ...
- 【BZOJ1367】[Baltic2004]sequence 左偏树
[BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...
- 【BZOJ3043】IncDec Sequence 乱搞
[BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...
- hdu 3397 Sequence operation(很有意思的线段树题)
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【HDOJ】5063 Operation the Sequence
#include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 100005 #defin ...
- 【线段树】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 ...
- 【HDOJ】2062 Subset sequence
这道题目非常好,饶了点儿圈子.我的思路是,先按照组排列.例如,1 2 31 2 2 1 3 11 2 3 2 1 3 ...
随机推荐
- log4j的properties详细配置,分级输出日志文件
log4j是很常用的日志类包,在此做一下配置的记录 加载jar包和properities配置文件 将commons-logging.jar和logging-lo ...
- 初建FreeMarker工程
初建FreeMarker工程 ——@梁WP 背景:听说freemarker可以用来写页面的组件,热衷于编写可重用代码的我,迫不及待地研究了freemarker,不过,在写组件之前,还是先研究一下fre ...
- jQuery滑动并响应事件
jQuery滑动并打开指定页面: <!DOCTYPE html> <html> <head> <script src="http://code.jq ...
- 11.12 noip模拟试题
题目名称 加密 冒泡排序图 重建可执行文件名 encrypt bubble rebuild输入文件名 encrypt.in bubble.in rebuild.in输出文件名 encrypt.in b ...
- JS手动创建标签
代码: <html> <head> <title>js标签属性的添加</title> <script > function setxxx() ...
- C#语法糖之第三篇: 匿名类 & 匿名方法
今天时间有点早,所以上来在写一篇文章吧,继续上一篇的文章,在我们平时编程过程中有没有遇到过这样的一个情景,你定义的类只是用来封装一些相关的数据,但并不需要相关联的方法.事件和其他自定义的功能.同时,这 ...
- asp.net - GridView根据linkButton值不同跳转不同页面
一,当前页面中,前台界面的主要代码: <asp:TemplateField HeaderText="姓名"> <ItemTemplate> <!--根 ...
- 使用openrowset跨库查询
--insert fj_studentinfo--select *--from-- openrowset('SQLOLEDB','localhost';'sa';'password',dbname. ...
- 详细介绍Linux shell脚本基础学习
Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提.1. Lin ...
- 推送消息实现icon角标的动态显示
在你自己服务器上做计数,客户端做减法并反馈给你的服务器 ,然后你服务器将需要显示的数字发送给苹果推送服务器(就是消息中的badge)比如:1,你服务器上发送出去3个推送消息到A手机 ...