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变成1,1变成0
3 a b 查询[a,b]区间1的个数
4 a b 查询[a,b]区间连续1最长的长度
思路:线段树线段合并。须要两个延迟标记一个置为01,一个翻转,然后因为4操作,须要记录左边最长0、1。右边最长0、1,区间最长0、1,然后区间合并去搞就可以
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)
const int N = 100005; int t, n, m; struct Node {
int l, r, sum[3][2], num;
int setv, flip;
Node() {
setv = -1;
flip = 0;
}
int size() {return r - l + 1;}
void gao1(int v) {
setv = v;
num = v * (r - l + 1);
for (int i = 0; i < 3; i++) {
sum[i][v] = r - l + 1;
sum[i][!v] = 0;
}
flip = 0;
}
void gao2() {
flip ^= 1;
for (int i = 0; i < 3; i++)
swap(sum[i][0], sum[i][1]);
num = r - l + 1 - num;
}
} node[N * 4]; Node merge(Node lson, Node rson) {
Node x;
x.l = lson.l; x.r = rson.r;
for (int i = 0; i < 2; i++) {
x.sum[0][i] = lson.sum[0][i];
x.sum[1][i] = rson.sum[1][i];
x.sum[2][i] = max(lson.sum[2][i], rson.sum[2][i]);
if (lson.sum[0][i] == lson.size())
x.sum[0][i] += rson.sum[0][i];
if (rson.sum[1][i] == rson.size())
x.sum[1][i] += lson.sum[1][i];
x.sum[2][i] = max(x.sum[2][i], lson.sum[1][i] + rson.sum[0][i]);
}
x.num = lson.num + rson.num;
return x;
} void pushup(int x) {
node[x] = merge(node[lson(x)], node[rson(x)]);
} void pushdown(int x) {
if (node[x].setv != -1) {
node[lson(x)].gao1(node[x].setv);
node[rson(x)].gao1(node[x].setv);
node[x].setv = -1;
}
if (node[x].flip) {
node[lson(x)].gao2();
node[rson(x)].gao2();
node[x].flip = 0;
}
} void build(int l, int r, int x = 0) {
node[x].l = l; node[x].r = r;
node[x].setv = -1; node[x].flip = 0;
if (l == r) {
int tmp;
scanf("%d", &tmp);
for (int i = 0; i < 3; i++) {
node[x].sum[i][tmp] = 1;
node[x].sum[i][!tmp] = 0;
}
node[x].num = tmp;
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
} void add(int l, int r, int v, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
if (v == 2) node[x].gao2();
else node[x].gao1(v);
return;
}
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
if (l <= mid) add(l, r, v, lson(x));
if (r > mid) add(l, r, v, rson(x));
pushup(x);
} Node query(int l, int r, int x = 0) {
if (node[x].l >= l && node[x].r <= r)
return node[x];
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
Node ans;
if (l <= mid && r > mid) ans = merge(query(l, r, lson(x)), query(l, r, rson(x)));
else if (l <= mid) ans = query(l, r, lson(x));
else if (r > mid) ans = query(l, r, rson(x));
pushup(x);
return ans;
} int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
build(0, n - 1);
int op, a, b;
while (m--) {
scanf("%d%d%d", &op, &a, &b);
if (op <= 2) add(a, b, op);
else if (op == 3) printf("%d\n", query(a, b).num);
else if (op == 4) printf("%d\n", query(a, b).sum[2][1]);
}
}
return 0;
}
HDU 3397 Sequence operation(线段树)的更多相关文章
- hdu 3397 Sequence operation (线段树 区间合并 多重标记)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...
- hdu 3397 Sequence operation 线段树
题目链接 给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数. 需要将数组开成二维的, 然后区间0, 1翻转只 ...
- hdu 3397 Sequence operation 线段树 区间更新 区间合并
题意: 5种操作,所有数字都为0或1 0 a b:将[a,b]置0 1 a b:将[a,b]置1 2 a b:[a,b]中的0和1互换 3 a b:查询[a,b]中的1的数量 4 a b:查询[a,b ...
- hdu 3397 Sequence operation(线段树:区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...
- hdu 3397 Sequence operation(很有意思的线段树题)
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【线段树】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 ...
- hdu-3397 Sequence operation 线段树多种标记
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目大意: 0 a b表示a-b区间置为0 1 a b表示a-b区间置为1 2 a b表示a- ...
- Sequence operation(线段树区间多种操作)
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu3397 Sequence operation 线段树
hdu3397 Sequence operation #include <bits/stdc++.h> using namespace std; ; struct node { /// l ...
随机推荐
- ThinkPHP - 常用的配置项
<?php return array( // 设置禁止访问的模块列表 // 'MODULE_DENY_LIST' => array('Common','Runtime','Api'), / ...
- AOP 笔记
http://blog.csdn.net/Intlgj/article/details/5671248 这篇文章里面介绍的非常好,值得阅读. 这里盗用里面的两张图片 [在没有AOP之前是这样的] [使 ...
- line
小君童靴说头儿给了他一个project,实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点.觉得这个很好玩,就自己也写了一点code /* date : 2014/10/21 version ...
- Week8(10月31日):并发
Part I:提问 =========================== 1. 更新关联.删除关联数据,需要注意哪些问题?以Instructor类为例说明. 2. 已知某请假系统,请实现以下界面的 ...
- Qt 文件监视器 QFileSystemWatcher
之前有过对Qt的QFile以Text纯文本方式进行读取时的学习,这两天由于实时需要又对QFileSystemWatcher(这个类是干什么用的)进行了学习,发现也是问题很让人头疼. 我想监视一个文件夹 ...
- c# 数据库编程(通过SqlCommand 执行数据库查询)
前面一篇文章,我们介绍了如何在c#中对数据库进行更新操作.主要是利用SqlCommand 对象的ExecuteNonQuery方法. 这篇文章介绍,如何进行查询操作.本文给出的例子仍然是针对sql s ...
- C#动态增加边框
if (this.Width >= 600) { timer1.Enabled = false; } else { this.Width += 30; }
- 深度优先搜索(DFS)递归形式改为非递归形式
DFS将递归改为非递归这个方法的需求来自于一道三维积木组合的题目,还在苦苦调试中,暂且不提. 普通的认识对于递归向非递归的转化无非是使用栈,但是结合到深度搜索如何将栈很好利用,如何很好保存现场,都不是 ...
- BZOJ 3163: [Heoi2013]Eden的新背包问题( 背包dp )
从左到右, 从右到左分别dp一次, 然后就可以回答询问了. ---------------------------------------------------------- #include< ...
- 我的Python成长之路---第一天---Python基础(1)---2015年12月26日(雾霾)
2015年12月26日是个特别的日子,我的Python成之路迈出第一步.见到了心目中的Python大神(Alex),也认识到了新的志向相投的伙伴,非常开心. 尽管之前看过一些Python的视频.书,算 ...