luoguP2572 [SCOI2010]序列操作
题目&&链接
反正数据都是一样的,luogu比较友好
luogu
bzoj
lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:
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
思路
每一步操作线段树都是可以维护的
但是,合起来也确实太恶心了点
维护 区间和,1的最长连续,前缀连续,后缀连续,
以及0的最长连续,前缀连续,后缀连续
7个值
以及两个lazy
一个是区间赋值的lazy1,一个是取反的lazy2
然后码代码就好了
注意*1
lazy下方的时候
只有三种情况
①先下方lazy1,后lazy2
②下方lazy1
③下方lazy2
因为如果是区间赋值的话,那么lazy2不lazy2的也没有啥子意义了
所以先lazy2,后lazy1这三种是被覆盖的
所以我们先下方lazy1
再下方lazy2
注意*2
还有,就是那个维护前缀后缀这种东西的时候
询问范围值不是int
因为你的答案不一定在线段树的一个儿子中,不能二分
所以要返回node_seg再进行选择
注意*3
写长代码的时候,像我一样没有一遍过变异的能力而且报错极多的
最后写一段编译一段,要不最后真的很绝望的
那些许多重复操作的
最好写点小函数之类的
减轻代码量
我只会输出调试,算了,不说了
/**************************************************************
Problem: 1858
User: 3010651817
Language: C++
Result: Accepted
Time:1496 ms
Memory:20436 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int maxn = 1e5 + 7;
int n, m, a[maxn];
struct node {
int l, r, size;
int lazy1 , lazy2;
int sum;
int lk, rk, k;
int lk_, rk_, k_;
void add(int a) {
lk = rk = k = sum = a;
}
void add_(int a) {
lk_ = rk_ = k_ = a;
sum = size - a;
}
void swap_() {
swap(k_, k);
swap(lk_, lk);
swap(rk_, rk);
sum = size - sum;
}
} e[maxn << 2];
void pushdown_lazy1(int rt) {
e[ls].add(e[rt].lazy1 * e[ls].size);
e[ls].add_((1 ^ e[rt].lazy1)*e[ls].size);
e[ls].lazy1 = e[rt].lazy1;
e[ls].lazy2 = 0;
e[rs].add(e[rt].lazy1 * e[rs].size);
e[rs].add_((1 ^ e[rt].lazy1)*e[rs].size);
e[rs].lazy1 = e[rt].lazy1;
e[rs].lazy2 = 0;
}
void pushdown_lazy2(int rt) {
e[ls].swap_();
e[ls].lazy2 = !e[ls].lazy2;
e[rs].swap_();
e[rs].lazy2 = !e[rs].lazy2;
}
int read() {
int x = 0, f = 1; char s = getchar();
for (; s < '0' || s > '9'; s = getchar()) if (s == '-') f = -1;
for (; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
return x * f;
}
int max_2(int a, int b, int c) {
return max(max(a, b), c);
}
void pushup(int rt) {
e[rt].sum = e[ls].sum + e[rs].sum;
e[rt].k = max_2(e[ls].k, e[rs].k, e[ls].rk + e[rs].lk);
e[rt].lk = (e[ls].lk == e[ls].size) ? e[ls].lk + e[rs].lk : e[ls].lk;
e[rt].rk = (e[rs].rk == e[rs].size) ? e[ls].rk + e[rs].rk : e[rs].rk;
e[rt].k_ = max_2(e[ls].k_, e[rs].k_, e[ls].rk_ + e[rs].lk_);
e[rt].lk_ = (e[ls].lk_ == e[ls].size) ? e[ls].lk_ + e[rs].lk_ : e[ls].lk_;
e[rt].rk_ = (e[rs].rk_ == e[rs].size) ? e[ls].rk_ + e[rs].rk_ : e[rs].rk_;
}
void pushdown(int rt) {
if (e[rt].lazy1 != -1)
pushdown_lazy1(rt);
if (e[rt].lazy2 == 1)
pushdown_lazy2(rt);
e[rt].lazy1 = -1;
e[rt].lazy2 = 0;
}
void build(int l, int r, int rt) {
e[rt].l = l, e[rt].r = r, e[rt].size = r - l + 1;
e[rt].lazy1 = -1, e[rt].lazy2 = 0;
if (l == r) {
e[rt].add(a[l]);
e[rt].add_(!a[l]);
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
pushup(rt);
}
void update_1(int L, int R, int k, int rt) {
if (L <= e[rt].l && e[rt].r <= R) {
e[rt].add(k * e[rt].size);
e[rt].add_((1 ^ k)*e[rt].size);
e[rt].lazy1 = k;
e[rt].lazy2 = 0;
return;
}
pushdown(rt);
int mid = (e[rt].l + e[rt].r) >> 1;
if (L <= mid) update_1(L, R, k, ls);
if (R > mid) update_1(L, R, k, rs);
pushup(rt);
}
void update_2(int L, int R, int rt) {
if (L <= e[rt].l && e[rt].r <= R) {
e[rt].swap_();
e[rt].lazy2 = !e[rt].lazy2;
return;
}
pushdown(rt);
int mid = (e[rt].l + e[rt].r) >> 1;
if (L <= mid) update_2(L, R, ls);
if (R > mid) update_2(L, R, rs);
pushup(rt);
}
int query_1(int L, int R , int rt) {
if (L <= e[rt].l && e[rt].r <= R) {
return e[rt].sum;
}
pushdown(rt);
int mid = (e[rt].l + e[rt].r) >> 1, ans = 0;
if (L <= mid) ans += query_1(L, R, ls);
if (R > mid) ans += query_1(L, R, rs);
pushup(rt);
return ans;
}
node query_2(int L, int R, int rt) {
if (L <= e[rt].l && e[rt].r <= R) {
return e[rt];
}
pushdown(rt);
int mid = (e[rt].l + e[rt].r) >> 1;
if (L <= mid && R > mid) {
node a = query_2(L, R, ls) , b = query_2(L, R, rs);
node tmp = {};
tmp.k = max_2(a.k, b.k, a.rk + b.lk);
tmp.lk = (a.lk == a.size) ? a.lk + b.lk : a.lk;
tmp.rk = (b.rk == b.size) ? a.rk + b.rk : b.rk;
return tmp;
} else if (L <= mid) return query_2(L, R, ls);
else if (R > mid) return query_2(L, R, rs);
}
int main() {
n = read(), m = read();
for (int i = 1; i <= n; ++i) {
a[i] = read();
}
build(1, n, 1);
for (int i = 1; i <= m; ++ i) {
int tmp = read(), a = read(), b = read();
a++, b++;
if (tmp == 0) {
update_1(a, b, 0, 1);
} if (tmp == 1) {
update_1(a, b, 1, 1);
} else if (tmp == 2) {
update_2(a, b, 1);
} else if (tmp == 3) {
printf("%d\n", query_1(a, b, 1));
} else if (tmp == 4) {
printf("%d\n", query_2(a, b, 1).k);
}
}
return 0;
}
luoguP2572 [SCOI2010]序列操作的更多相关文章
- bzoj 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...
- BZOJ 1858: [Scoi2010]序列操作( 线段树 )
略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...
- bzoj1858[Scoi2010]序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 3079 Solved: 1475[Submit][Statu ...
- BZOJ_1858_[Scoi2010]序列操作_线段树
BZOJ_1858_[Scoi2010]序列操作_线段树 Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询 ...
- 【题解】Luogu P2572 [SCOI2010]序列操作
原题传送门:P2572 [SCOI2010]序列操作 这题好弱智啊 裸的珂朵莉树 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 操作1:把区间内所有数推平成0,珂朵莉树基本操作 ...
- P2572 [SCOI2010]序列操作
对自己 & \(RNG\) : 骄兵必败 \(lpl\)加油! P2572 [SCOI2010]序列操作 题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要 ...
- BZOJ1858 [Scoi2010]序列操作(线段树)
题目链接 [Scoi2010]序列操作 考验代码能力的一道好题. 思想还是很简单的(直接上线段树),但是比较难写. #include <bits/stdc++.h> using names ...
- (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作
二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...
- 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 3397 Solved: 1624 [Submit][Statu ...
随机推荐
- 火币Huobi API Websocket
本文介绍火币Huobi API Websocket WebSocket API简介 WebSocket协议是基于TCP的一种新的网络协议.它实现了客户端与服务器之间在单个 tcp 连接上的全双工通信, ...
- 学习计划 mysql 用户管理与权限
最近在学习数据库的 主从复制 里面涉及到了关于用户及其管理权限的赋予,之前一直没有认真的学习这个. 现在想具体的学习一下. -- 为什么 数据库 要实现多用户管理? 举个最简单的例子,你需要和第三方做 ...
- 2018/04/01 每日一个Linux命令 之 sleep
今天看到一个很有意思的指令. sleep [睡觉/休眠] 的意思. 可以用来将目前动作延迟一段时间.之后触发 -- sleep number[smhd] 重要参数 number : 时间长度,后面可接 ...
- Memcached集群架构方面的问题(转)
add by zhj: 这是一个系列中的第二篇,该系列有四篇,英文原文没找到,译文见:http://blog.csdn.net/jarfield/article/details/4336035 ,附上 ...
- 缓存淘汰算法(LFU、LRU、ARC、FIFO、MRU)分析
缓存算法是指令序列,用于决定缓存系统中哪些数据应该被删去. 常见类型包括LFU.LRU.ARC.FIFO.MRU. 一.最不经常使用算法(Least Frequently Used-LFU): 它是基 ...
- Dubbo简单环境搭建
Dubbo服务的发展和作用: 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后的常规方案演进历程. 其次,当服务越来越多之后,我们需要做哪些服务治理? 最后,是d ...
- mysql 数据表操作 存储引擎介绍
一 什么是存储引擎? 存储引擎就是表的类型. mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制 ...
- 顺序结构,判断结构 if,switch
1:顺序结构:从上往下执行程序代码,为顺序结构 ---------------------------------------------------------------------- 2:判断结 ...
- edgeR使用学习【转载】
转自:http://yangl.net/2016/09/27/edger_usage/ 1.Quick start 2. 利用edgeR分析RNA-seq鉴别差异表达基因: #加载软件包 librar ...
- col-md-1
.col-md-12 { width: 100%; } .col-md-11 { width: 91.66666666666666%; } .col-md-10 { widt ...