【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 ...
随机推荐
- 详解android:scaleType属性
详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262 http://juliaailse. ...
- C#有关 字符串方法的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- CSS 尺寸 (Dimension)
CSS 尺寸 (Dimension) 属性允许你控制元素的高度和宽度.同样,它允许你增加行间距. 更多实例 设置元素的高度 这个例子演示了如何设置不同元素的高度. 使用百分比设置图像的高度 这个例子演 ...
- CSS Outlines
轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用. 轮廓(outline)属性指定了样式,颜色和外边框的宽度. 轮廓(outline)实例 在元素周围画线本例演 ...
- 配置wamp开发环境【2】 配置wamp开发环境之mysql的配置
此前我已经将wamp配置的Apache.PHP.phpmyadmin全部配置完成,以上三种配置参照 配置wamp开发环境 下面我们来看看mysql的配置,这里用的是mysql5.5.20,下载地址: ...
- 前端开发构建工具gulp的安装使用
曾几何时还在使用grunt作为前端的构建工具,直到有一天同事向我推荐了gulp,在这里博主将不讨论gulp与grunt各自优势的比较,只为大家介绍gulp如何安装和使用. Gulp 是用 nodejs ...
- 网络编程(学习整理)---3--(Udp)FeiQ实现广播消息群发
1.广播群发消息: 这里使用的任然是UDP协议,使用方法还是比较简单的! 我就记录一下需要注意的一些地方(笔记): (1)这里是在局域网内,借用FeiQ聊天软件,编写一段程序,实现对局域网内的每一个登 ...
- STP根交换机,指定端口,根端口,阻塞端口
STP判断各交换机端口(指定端口:DP;根端口:RP;阻塞端口:AP) 判断步骤: 1.选举根交换机: 判断对象:所有运行STP协议的交换机中选出一个; 判断依据:交换机中选择网桥ID值(交换机优先级 ...
- P次方数 英雄会 csdn 高校俱乐部
题目: 一个整数N,|N| >= 2, 如果存在整数x,使得N = x * x * x... (p个x相乘) =x^p,则称N是p次方数,给定32位内的整数N,求最大的P.例如N=5,输出1,N ...
- Codeforces 553C Love Triangles(图论)
Solution: 比较好的图论的题. 要做这一题,首先要分析love关系和hate关系中,love关系具有传递性.更关键的一点,hate关系是不能成奇环的. 看到没有奇环很自然想到二分图的特性. 那 ...