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(线段树)的更多相关文章

  1. hdu 3397 Sequence operation (线段树 区间合并 多重标记)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...

  2. hdu 3397 Sequence operation 线段树

    题目链接 给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数. 需要将数组开成二维的, 然后区间0, 1翻转只 ...

  3. 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 ...

  4. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

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

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

  6. 【线段树】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 ...

  7. 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- ...

  8. Sequence operation(线段树区间多种操作)

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

  9. hdu3397 Sequence operation 线段树

    hdu3397 Sequence operation #include <bits/stdc++.h> using namespace std; ; struct node { /// l ...

随机推荐

  1. JavaScript 高级程序设计(第3版)笔记——chapter3:基本概念(函数部分)

    3.7函数 3.7.1 理解参数 ECMAScript 函数不介意传递进来多个参数,也不在乎传递进来的参数是什么数据类型.因为在 ECMAScript 中的参数在内部是用一个数组来表示的.在函数体内可 ...

  2. 【JavaScript】history.back() 网页已过期

    使用history.back()进行返回时,有时会提示“网页已过期”, 多数是因为目标页面的form为post提交方式,而且是表单已经提交后的响应页面,无法找到form中的具体参数,而“报错”. 具体 ...

  3. c++ 虚析构函数[避免内存泄漏]

    c++  虚析构函数: 虚析构函数(1)虚析构函数即:定义声明析构函数前加virtual 修饰, 如果将基类的析构函数声明为虚析构函数时,由该基类所派生的所有派生类的析构函数也都自动成为虚析构函数. ...

  4. HDU 5025Saving Tang Monk BFS + 二进制枚举状态

    3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间. 第二次WA,是因为没有枚举蛇的状态. 解体思路: 因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可. 然后多次BFS, ...

  5. struts2上传图片

    在WEB-INF下新建一个content目录,建立一个upload.jsp <%@ page contentType="text/html; charset=UTF-8" l ...

  6. activebar的用法

    效果图: 网站页面上弹出消息提示狂,用来提示重大事件. <script src="http://www.ijquery.cn/js/jquery-1.7.2.min.js"& ...

  7. DE1-SOC连接设定

    将电源供应器插上电源接口. 使用白色的USB Type B线材将计算机与DE1-SoC上的USB-Blaster II接口连接.此接口主要负责FPGA配置以及HPS Debug使用. 使用Mini-U ...

  8. MediaPlayer视频播放器

    android视频播放 根据apidemo重写.代码如下: package com.jamdeo.tv.livetv.player; import android.media.AudioManager ...

  9. mongodb副本集自动切换修复节点解决方案

    副本集部署 1.启动mongod 在每台运行mongod服务的机器上增加配置文件/etc/mongodb-rs.conf,内容为: [root@MongodbF-A etc]# vi /etc/mon ...

  10. Mysql 启动失败 报错 1067

    Mysql装好后,重启电脑第二次发现服务无法启动.提示如下: ------------------------ MySQL 服务无法启动. 系统出错. 发生系统错误 1067. 进程意外终止. --- ...