题意:

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]中的最长连续1串的长度

这题看题目就很裸,综合了区间更新,区间合并

我一开始把更新操作全放一个变量,但是在push_down的时候很麻烦,情况很多,容易漏,后来改成下面的

更新的操作可以分为两类,一个是置值(stv),一个是互换(swp)。如果stv!=-1,则更新儿子节点的stv,并将儿子的swp=0。如果swp=1,这里要注意一点,不是把儿子的swp赋值为1,而是与1异或!!!因为如果儿子的swp本为1,再互换一次,两个互换就相当于值没有变了。

注意下细节就行了

#include <bits/stdc++.h>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std; const int MAXN = 111111; struct Node
{
int num1, stv, swp;
int mx0, lmx0, rmx0;
int mx1, lmx1, rmx1;
} tr[MAXN<<2]; void changeto(int rt, int to,int len)
{
tr[rt].mx0 = tr[rt].lmx0 = tr[rt].rmx0 = to? 0 : len;
tr[rt].mx1 = tr[rt].lmx1 = tr[rt].rmx1 = tr[rt].num1 = to? len : 0;
} void exchange(int rt, int len)
{
tr[rt].num1 = len - tr[rt].num1;
swap(tr[rt].mx0, tr[rt].mx1);
swap(tr[rt].lmx0, tr[rt].lmx1);
swap(tr[rt].rmx0, tr[rt].rmx1);
} void push_down(int rt, int len)
{
if(tr[rt].stv != -1)
{
tr[rt<<1].stv = tr[rt<<1|1].stv = tr[rt].stv;
tr[rt<<1].swp = tr[rt<<1|1].swp = 0;
changeto(rt<<1, tr[rt].stv, len-(len>>1));
changeto(rt<<1|1, tr[rt].stv, len>>1);
tr[rt].stv = -1;
}
if(tr[rt].swp == 1)
{
tr[rt<<1].swp ^= 1;
tr[rt<<1|1].swp ^= 1;
exchange(rt<<1, len-(len>>1));
exchange(rt<<1|1, len>>1);
tr[rt].swp = 0;
}
} void push_up(int rt, int len)
{
tr[rt].num1 = tr[rt<<1].num1 + tr[rt<<1|1].num1; tr[rt].lmx0 = tr[rt<<1].lmx0;
tr[rt].rmx0 = tr[rt<<1|1].rmx0;
if(tr[rt].lmx0 == len - (len >> 1)) tr[rt].lmx0 += tr[rt<<1|1].lmx0;
if(tr[rt].rmx0 == len >> 1) tr[rt].rmx0 += tr[rt<<1].rmx0;
tr[rt].mx0 = max(tr[rt<<1].rmx0 + tr[rt<<1|1].lmx0, max(tr[rt<<1].mx0, tr[rt<<1|1].mx0)); tr[rt].lmx1 = tr[rt<<1].lmx1;
tr[rt].rmx1 = tr[rt<<1|1].rmx1;
if(tr[rt].lmx1 == len - (len >> 1)) tr[rt].lmx1 += tr[rt<<1|1].lmx1;
if(tr[rt].rmx1 == len >> 1) tr[rt].rmx1 += tr[rt<<1].rmx1;
tr[rt].mx1 = max(tr[rt<<1].rmx1 + tr[rt<<1|1].lmx1, max(tr[rt<<1].mx1, tr[rt<<1|1].mx1));
} void build(int l, int r, int rt)
{
tr[rt].stv = -1;
tr[rt].swp = 0;
if(l == r)
{
scanf("%d", &tr[rt].num1);
tr[rt].mx0 = tr[rt].lmx0 = tr[rt].rmx0 = tr[rt].num1 ^ 1;
tr[rt].mx1 = tr[rt].lmx1 = tr[rt].rmx1 = tr[rt].num1;
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt, r-l+1);
} void update(int L, int R, int op, int l, int r, int rt)
{
if(L <= l && r <= R)
{
if(op == 0 || op == 1)
{
changeto(rt, op, r-l+1);
tr[rt].stv = op;
tr[rt].swp = 0;
}
else
{
exchange(rt, r-l+1);
tr[rt].swp ^= 1;
}
return;
}
push_down(rt, r-l+1);
int m = (l + r) >> 1;
if(m >= L) update(L, R, op, lson);
if(m < R) update(L, R, op, rson);
push_up(rt, r-l+1);
} int query1(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) return tr[rt].num1;
push_down(rt, r-l+1);
int m = (l + r) >> 1;
int ret = 0;
if(m >= L) ret += query1(L, R, lson);
if(m < R) ret += query1(L, R, rson);
return ret;
} int query2(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) return tr[rt].mx1;
push_down(rt, r-l+1);
int m = (l + r) >> 1;
int ret = 0;
if(m >= L) ret = max(ret, query2(L, R, lson));
if(m < R) ret = max(ret, query2(L, R, rson));
ret = max(ret, min(tr[rt<<1].rmx1, m-L+1) + min(tr[rt<<1|1].lmx1, R-m));
return ret;
} int main()
{
// freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
int n, m;
scanf("%d%d", &n, &m);
build(0, n-1, 1);
while(m--)
{
int op, x, y;
scanf("%d%d%d", &op, &x, &y);
if(op <= 2) update(x, y, op, 0, n-1, 1);
else if(op == 3) printf("%d\n", query1(x, y, 0, n-1, 1));
else printf("%d\n", query2(x, y, 0, n-1, 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(线段树)

    HDU 3397 Sequence operation 题目链接 题意:给定一个01序列,有5种操作 0 a b [a.b]区间置为0 1 a b [a,b]区间置为1 2 a b [a,b]区间0变 ...

  4. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  5. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  7. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

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

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

  9. HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)

    Fast Arrangement Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. Git-【技术干货】工作中Git的使用实践

    Git-[技术干货]工作中Git的使用实践 置顶 2019-09-17 21:02:16 web洋仔 阅读数 11444更多 分类专栏: Git   版权声明:本文为博主原创文章,遵循CC 4.0 B ...

  2. WORD表格中的文字总是靠上居中不了

    WORD表格中的文字总是靠上居中不了 将表格选中 然后,点击格式工具栏里的格式(第一个项目)右侧的小三角(通常显示为正文),选择清除格式,然后,再用表格与边框工具栏中的居中功能设置居中就可以了 将表格 ...

  3. mysql8 安装配置教程

    第一步 下载安装包 MySQL 是甲骨文(Oracle)公司产品,可以到官网上下载 MySQL: 官网下载地址:https://dev.mysql.com/downloads/mysql/ 如果嫌弃官 ...

  4. 03丨认识文档数据库MongoDB

  5. svg 飞线,源码

    <html> <head> <meta charset="utf-8" /> <meta name="viewport" ...

  6. 【遥感数字图像处理实验】Erdas版详细图文实验教程(8实验全)

    @ 目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 遥感数字图像的处理,是对遥感数字图像的计算机处理.与工业和医学数字图像不同,遥感数字图像类型更为多样,内容更为复杂.因此,遥感 ...

  7. ES6笔记2

    ES6笔记2 Promise Promise 是 ES6 引入的异步编程的新解决方案,语法上是一个构造函数 一共有3种状态,pending(进行中).fulfilled(已成功)和rejected(已 ...

  8. The Superego 实验四 团队作业1:软件研发团队组建

    项目 内容 课程班级博客链接 班级博客链接 这个作业要求链接 作业要求链接 团队名称 The Superego 团队的课程学习目标 (1)组建团队,建设团队文化,申请开通团队博客 (2)团队之间相互协 ...

  9. 一文搞懂Ajax,附Ajax面试题

    目录 前言 正文 Ajax是什么东西? 实现核心/工作原理:XMLHttpRequest对象 XMLHttpRequest大致用法 创建XMLHttpRequest对象 发送请求 服务器响应 1. r ...

  10. 『居善地』接口测试 — 12、Moco框架介绍

    目录 1.Mock功能介绍 2.Moco框架介绍 3.Moco框架在接口测试中的作用 4.Moco框架的优点 5.Moco框架的下载与启动 (1)Moco框架的下载 (2)Moco框架的启动 1.Mo ...