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 ...
随机推荐
- windows下取linux系统里面的文件
方法一:使用原生态的psftp 1.下载psftp.exe http://pan.baidu.com/s/1boVLHKF 2.双击psftp.exe 2.1 输入指令:open IP地址 (例如:o ...
- 在主函数中提示用户输入用户名和密码。另写一方法来判断用户输入是否正确。该方法分别返回一个bool类型的登录结果和和一个string类型的登录信息。如登录成功,返回true及“登录成功”,若登录失败则返回false及“用户名错误”或“密码错误”(使用out参数)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- [Swust OJ 715]--字典序问题(组合数预处理/数位dp)
题目链接:http://acm.swust.edu.cn/problem/715/ Time limit(ms): 1000 Memory limit(kb): 65535 在数据加密和数据压缩中 ...
- 安装帝国CMS遇到“修改php.ini,将:short_open_tag 设为 On”的解决方法+“建立目录不成功!请检查目录权限”问题
想用安装个帝国CMS来做个网站,于是下载了程序,上传到服务器上,但是在输入安装路径的时候却给出了如下图示: 您的PHP配置文件php.ini配置有问题,请按下面操作即可解决: 1.修改php.ini, ...
- Spring MVC整体处理流程
一.spring整体结构 首先俯视一下spring mvc的整体结构 二.处理流程 1.请求处理的第一站就是DispatcherServlet.它是整个spring mvc的控制核心.与大多数的jav ...
- QT窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透
qt 窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透 窗口置顶qt 里是 setWindowFlags(Qt::WindowStaysOnTopHint)kde 里 ...
- Python 2.7 学习笔记 基本知识
python是一种解释型的.面向对象的.带有动态语义的高级程序设计语言.本文介绍下python的基本知识. 一.安装 各种操作系统有自己的安装方法,linux系统一般都自带了python的环境.这里不 ...
- JavaScript下全选反选的Demo程序里实现checkmeonly函数 DOM
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Windows Phone 8初学者开发—第20部分:录制Wav音频文件
原文 Windows Phone 8初学者开发—第20部分:录制Wav音频文件 原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Develop ...
- 17.1 Replication Configuration 复制:
17.1 Replication Configuration 复制: 17.1.1 How to Set Up Replication 17.1.2 Replication Formats 17.1. ...