线段树 区间合并 F - Sequence operation
F - Sequence operation
题解:
这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,
这个有两个地方要注意一下,一个是取反的lazy标志,每次取反都是对1取异或,还有一个也是这个取反的lazy标志,
这个标志再第一种操作之后要进行消除。
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <iostream>
#include <stack>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
struct node
{
int sum;
int max_sub, max_zero;
int l, r, len;
int lazy1, lazy2;
int max_prezero, max_lastzero;
int max_preone, max_lastone;
}tree[maxn * ];
int a[maxn]; void push_up(int id)
{
tree[id].sum = tree[id << ].sum + tree[id << | ].sum; tree[id].max_preone = tree[id << ].max_preone;
if (tree[id].max_preone == tree[id << ].len) tree[id].max_preone += tree[id << | ].max_preone;
tree[id].max_lastone = tree[id << | ].max_lastone;
if (tree[id].max_lastone == tree[id << | ].len) tree[id].max_lastone += tree[id << ].max_lastone;
tree[id].max_sub = max(tree[id << ].max_lastone + tree[id << | ].max_preone, max(tree[id << ].max_sub, tree[id << | ].max_sub)); tree[id].max_prezero = tree[id << ].max_prezero;
if (tree[id].max_prezero == tree[id << ].len) tree[id].max_prezero += tree[id << | ].max_prezero;
tree[id].max_lastzero = tree[id << | ].max_lastzero;
if (tree[id].max_lastzero == tree[id << | ].len) tree[id].max_lastzero += tree[id << ].max_lastzero;
tree[id].max_zero = max(tree[id << ].max_lastzero + tree[id << | ].max_prezero, max(tree[id << ].max_zero, tree[id << | ].max_zero)); return;
} void chang1(int id, int val)
{
if (val)
{
tree[id].sum = tree[id].len;
tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = tree[id].len;
tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = ;
}
else
{
tree[id].sum = ;
tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = ;
tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = tree[id].len;
}
} void chang2(int id)
{
swap(tree[id].max_sub, tree[id].max_zero);
swap(tree[id].max_prezero, tree[id].max_preone);
swap(tree[id].max_lastone, tree[id].max_lastzero);
tree[id].sum = tree[id].len - tree[id].sum;
} void push_down(int id)
{
if (tree[id].lazy1)
{
chang1(id << , tree[id].lazy1 - );
chang1(id << | , tree[id].lazy1 - );
tree[id << ].lazy1 = tree[id << | ].lazy1 = tree[id].lazy1;
tree[id << ].lazy2 =tree[id << | ].lazy2 = ;
tree[id].lazy1 = ;
}
if (tree[id].lazy2)
{
chang2(id << );
chang2(id << | ); tree[id << ].lazy2 ^= ;
tree[id << | ].lazy2 ^= ;
tree[id].lazy2 = ;
}
} void build(int id, int l, int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lazy1 = ;
tree[id].lazy2 = ;
tree[id].len = r - l + ;
if (l == r)
{
if (a[l]) chang1(id, );
else chang1(id, );
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
push_up(id);
} void update_change(int id, int l, int r, int z)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
chang1(id, z);
tree[id].lazy1 = z + ;
tree[id].lazy2 = ;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) update_change(id << , l, r, z);
if (r > mid) update_change(id << | , l, r, z);
push_up(id);
} void update_trans(int id, int l, int r)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
tree[id].lazy2 ^= ;
chang2(id);
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) update_trans(id << , l, r);
if (r > mid) update_trans(id << | , l, r);
push_up(id);
} int query_sum(int id, int l, int r)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
return tree[id].sum;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> , ans = ;
if (l <= mid) ans += query_sum(id << , l, r);
if (r > mid) ans += query_sum(id << | , l, r);
return ans;
} int query(int id, int l, int r)
{
int ans = ;
if (l <= tree[id].l&&r >= tree[id].r)
{
return tree[id].max_sub;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) ans = max(ans, query(id << , l, r));
if (r > mid) ans = max(ans, query(id << | , l, r));
ans = max(ans, min(mid - l + , tree[id << ].max_lastone) + min(r - mid, tree[id << | ].max_preone));
return ans;
} int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
build(, , n);
while (m--)
{
int c, x, y;
scanf("%d%d%d", &c, &x, &y);
if (c == ) update_change(, x + , y + , );
if (c == ) update_change(, x + , y + , );
if (c == ) update_trans(, x + , y + );
if (c == )
{
int ans = query_sum(, x + , y + );
printf("%d\n", ans);
}
if (c == )
{
int ans = query(, x + , y + );
printf("%d\n", ans);
}
}
}
return ;
}
线段树 区间合并 F - Sequence operation的更多相关文章
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
- poj3667 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- hdu3911 线段树 区间合并
//Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- 树链剖分——线段树区间合并bzoj染色
线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...
- poj3667 Hotel (线段树 区间合并)
poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...
- hdu-3308 LCIS (线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- Tunnel Warfare(HDU1540+线段树+区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目: 题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的 ...
- hdu 3308(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
随机推荐
- 虚拟机VMware 安装后虚拟机网卡与主机网卡数据交换关系
安装好虚拟机以后,在网络连接里面可以看到多了两块网卡: 其中VMnet1是虚拟机Host-only模式的网络接口,VMnet8是NAT模式的网络接口,这些后面会详细介绍.在VMware Worksta ...
- AJ学IOS(21)UIApplication设置程序图标右上⾓红⾊数字_联⺴指⽰器等
AJ分享,必须精品 效果简介 UIApplication的运用,有很多相如:进⾏行⼀一些应⽤用级别的操作等等,打开网页,打开电话拨号和信息等.. 什么是UIApplication ● UIApplic ...
- Android调用系统设置
最近,弄了一下,调用系统设置的方法,Android4.0的系统,下面的所有设置项,都亲测可以调用.首先调用的方式如下: Intent mintent_setting_time = new Intent ...
- win10下cuda安装以及利用anaconda安装pytorch-gpu过程
安装环境:win10+2070super 1.Cuda的下载安装及配置 (1)测试本机独立显卡是否支持CUDA的安装,点击此处查询显卡是否在列表中. (2)查看自己是否能右键找到NVIDA控制面板,如 ...
- 今天探究的CSS属性是box-sizing;
首先BOX-SIZING属性是CSS3的属性: 语法: box-sizing : content-box || border-box || inherit 取值说明 1.content-box:此值为 ...
- UnicodeDecodeError: 'gbk' codec can't decode byte 0x8a in position 2: illegal multibyte sequence
pycharm报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x8a in position 2: illegal multibyte seq ...
- MySql --FIND_IN_SET() 函数 (转)
例子:https://www.jianshu.com/p/b2c1ba0ba34f 举个例子来说:有个文章表里面有个type字段,他存储的是文章类型,有 1头条,2推荐,3热点,4图文 .....11 ...
- 2019-2020-1 20199326《Linux内核原理与分析》第二周作业
本周总结:本周的学习内容主要是庖丁解牛Linux的第一章,然后看完书后,又跟着云班课加深学习了一下第一章的内容.第一章主要讲述了linux里的汇编指令的一些指令,比如movl,pushl,popl等等 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第六周作业
<Linux内核原理与分析>第六周作业 一.本周内容概述: 学习系统调用的相关理论知识,并使用库函数API和C代码中嵌入汇编代码两种方式使用getpid()系统调用 学习系统调用syste ...
- How to skip all the wizard pages and go directly to the installation process?
https://stackoverflow.com/questions/22183811/how-to-skip-all-the-wizard-pages-and-go-directly-to-the ...