hdu3397 Sequence operation

 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+;
struct node {
/// l,r表示当前结点区间范围[l,r]
int l, r;
/// val=0时为全0标志,表示区间[l,r]的值全为0
/// val=1时为全1标志,表示区间[l,r]的值全为1
/// val=-1时则代表无操作
/// xor为异或标志,表示区间[l,r]的值取异或操作
int val, Xor;
/// lmax_0表示区间[l,r]从左往右开始连续0的个数
/// rmax_0表示区间[l,r]从右往左开始连续0的个数
/// max_0表示当前区间最大连续0的个数
int lmax_0, rmax_0, max_0, sum_0;
int lmax_1, rmax_1, max_1, sum_1;
/// 得到当前区间长度
int len() { return r-l+; } /// 更新操作,val_代表01操作,xor_代表异或操作
void change(int val_, int Xor_) {
/// [l,r]全置为0
if (val_ == ) {
lmax_0 = rmax_0 = max_0 = sum_0 = len();
lmax_1 = rmax_1 = max_1 = sum_1 = ;
val = , Xor = ;
}
/// [l,r]全置为1
else if (val_ == ) {
lmax_0 = rmax_0 = max_0 = sum_0 = ;
lmax_1 = rmax_1 = max_1 = sum_1 = len();
val = , Xor = ;
}
/// [l,r]全异或
if (Xor_ == ) {
swap(lmax_0,lmax_1); swap(rmax_0,rmax_1);
swap(max_0,max_1); swap(sum_0,sum_1);
Xor ^= ;
}
}
}tree[maxn*];
int a[maxn];
void pushup(node &fa, node &ls, node &rs) {
/// 父节点的左边最长0串=左子树的左边最长0串
fa.lmax_0 = ls.lmax_0, fa.rmax_0 = rs.rmax_0;
fa.lmax_1 = ls.lmax_1, fa.rmax_1 = rs.rmax_1;
/// 父节点0的数量=左子树0的数量+右子树0的数量
fa.sum_0 = ls.sum_0+rs.sum_0;
fa.sum_1 = ls.sum_1+rs.sum_1;
/// 父节点最大连续0串等于左右子树里面中最大连续0串的最大值
/// 或者是左子树从右开始的0串+右子树从左开始的0串之和
fa.max_0 = max(max(ls.max_0,rs.max_0), ls.rmax_0+rs.lmax_0);
fa.max_1 = max(max(ls.max_1,rs.max_1), ls.rmax_1+rs.lmax_1); /// 如果左子树整串都为0串
if (ls.len() == ls.lmax_0) fa.lmax_0 += rs.lmax_0;
if (ls.len() == ls.lmax_1) fa.lmax_1 += rs.lmax_1;
if (rs.len() == rs.rmax_0) fa.rmax_0 += ls.rmax_0;
if (rs.len() == rs.rmax_1) fa.rmax_1 += ls.rmax_1;
}
void pushdown(int rt) {
if (tree[rt].val != - || tree[rt].Xor) {
tree[rt*].change(tree[rt].val,tree[rt].Xor);
tree[rt*+].change(tree[rt].val,tree[rt].Xor);
tree[rt].val = -, tree[rt].Xor = ;
}
}
void build(int rt, int l, int r) {
/// 结点初始化
tree[rt].l = l, tree[rt].r = r;
tree[rt].lmax_0 = tree[rt].rmax_0 = ;
tree[rt].lmax_1 = tree[rt].rmax_1 = ;
tree[rt].max_0 = tree[rt].max_1 = ;
tree[rt].sum_0 = tree[rt].sum_1 = ;
tree[rt].Xor = , tree[rt].val = -;
/// 如果是叶子结点
if (l == r) {
tree[rt].change(a[l],);
return;
}
int mid = (l+r)/;
build(rt*,l,mid);
build(rt*+,mid+,r);
pushup(tree[rt],tree[rt*],tree[rt*+]);
}
void update(int rt, int l, int r, int op) {
int L = tree[rt].l, R = tree[rt].r;
if (l <= L && R <= r) {
/// 根据op执行不同操作
if (op == || op == ) tree[rt].change(op,);
else if (op == ) tree[rt].change(-,);
return;
}
pushdown(rt);
int mid = (L+R)/;
if (mid >= l) update(rt*,l,r,op);
if (mid < r) update(rt*+,l,r,op);
pushup(tree[rt],tree[rt*],tree[rt*+]);
}
int query(int rt, int l, int r, int op) {
int L = tree[rt].l, R = tree[rt].r;
if (l <= L && R <= r) {
if (op == ) return tree[rt].sum_1;
else if (op == ) return tree[rt].max_1;
}
int mid = (L+R)/;
pushdown(rt);
if (r <= mid) return query(rt*,l,r,op);
else if (l > mid) return query(rt*+,l,r,op);
else {
int max1 = query(rt*,l,r,op);
int max2 = query(rt*+,l,r,op);
if (op == ) return max1+max2;
int max3 = min(tree[rt*].r-l+,tree[rt*].rmax_1)+min(r-tree[rt*+].l+,tree[rt*+].lmax_1);
return max(max(max1,max2),max3);
}
}
int main() {
int t; scanf("%d",&t);
while (t--) {
int n, m; scanf("%d%d",&n,&m);
for (int i = ; i < n; ++i)
scanf("%d",&a[i]);
build(,,n-);
while (m--) {
int op, a, b;
scanf("%d%d%d",&op,&a,&b);
if (op == || op == || op == ) update(,a,b,op);
else printf("%d\n",query(,a,b,op));
}
}
return ;
}

hdu3397 Sequence operation 线段树的更多相关文章

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

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

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

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

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

  4. hdu 3397 Sequence operation 线段树

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

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

  6. HDU 4893 Wow! Such Sequence! (线段树)

    Wow! Such Sequence! 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4893 Description Recently, Doge ...

  7. HDU 5828 Rikka with Sequence (线段树)

    Rikka with Sequence 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  8. Codeforces Round #250 (Div. 1) D. The Child and Sequence(线段树)

    D. The Child and Sequence time limit per test 4 seconds memory limit per test 256 megabytes input st ...

  9. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor 线段树模拟

    E. Correct Bracket Sequence Editor   Recently Polycarp started to develop a text editor that works o ...

随机推荐

  1. STM32 内存分配解析及变量的存储位置

    内存映射 在一些桌面程序中,整个内存映射是通过虚拟内存来进行管理的,使用一种称为内存管理单元(MMU)的硬件结构来将程序的内存映射到物理RAM.在对于 RAM 紧缺的嵌入式系统中,是缺少 MMU 内存 ...

  2. 从零开始学习docker之在docker中搭建redis(单机)

    docker搭建redis 一.环境准备 云环境:CentOS 7.6 64位 二.下载镜像 从docker hub中找到redis镜像 传送门------https://hub.docker.com ...

  3. appium同时运行两台真机

    执行命令: appium -p 4494 -bp 2253 -U GWY0217207001793 appium -p 4493 -bp 2252 -U 77fdaabc server 设置:http ...

  4. PHP的yield是个什么玩意

    来源:https://segmentfault.com/a/1190000018457194 其实,我并不是因为迭代或者生成器或者研究PHP手册才认识的yield,要不是协程,我到现在也不知道PHP中 ...

  5. 宝塔利用git+ webhooks 实现git更新远程同步Linux服务器

    参考: https://blog.csdn.net/alipea/article/details/83858177 https://www.bt.cn/bbs/thread-5348-1-1.html ...

  6. Windows API Index

    https://docs.microsoft.com/en-us/windows/desktop/apiindex/windows-api-list

  7. 二进制安装MySQL及破解密码

    二进制安装MySQL及破解密码 1.确保系统中有依赖的libaio 软件,如果没有: yum -y install libaio 2.解压二进制MySQL软件包 tar xf mysql-5.7.24 ...

  8. linux rpm包

    rpm包,软件包,程序包,以.rpm结尾的包 我们刚开始安装的Linux系统是最小化安装(minimol),只安装系统,不安装不必要的软件包 刚开始vim,ifconfig,tree等命令都没有,当然 ...

  9. Java反射与注解

    反射 能够分析类能力的程序称为反射(reflective),代码的这种能力称为"自省".反射机制的功能极其强大,反射机制可以用来: 在运行时分析类的能力 在运行时查看对象,例如,编 ...

  10. Jenkins 邮件收发(qq 邮箱)

    一.配置 Jenkins 邮箱的全局配置 检查是否已安装插件 Email Extension Plugin 获取 qq 邮箱 授权码 进入 qq 邮箱 ---> 设置 ---> 账户 配置 ...