SCOI 2010 序列操作
题目描述
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
对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?
一道坑爹的线段树,我们维护7个信息,区间左右段点值,左右端点的连续长度,区间内的最长0串和1串。注意标记合并,翻转标记是xor更新的。覆盖标记遇上翻转标记是改覆盖标记类型。或者覆盖。
#include<bits/stdc++.h>
#define sight(x) ('0'<=x&&x<='9')
#define MID ((l+r)>>1)
#define max(x,y) (x)>(y)?(x):(y)
#define node No
#define o(x) (x=(x&1)+1)
#define L(x) ((x)<<1)
#define R(x) ((x)<<1|1)
#define La lazy
#define N 400007
using namespace std;
inline void read(int &x) {
static char c; static int b;
for (b=,c=getchar();!sight(c);c=getchar()) if (c=='-') b=-;
for (x=;sight(c);c=getchar()) x=x*+c-;
x*=b;
}
struct Node{
int sum,l,r,llen,rlen,ma[],siz;
inline void add(Node x,Node y){
sum=x.sum+y.sum; siz=x.siz+y.siz;
l=x.l; r=y.r;
ma[]=max(x.ma[],y.ma[]); ma[]=max(x.ma[],y.ma[]);
if (x.r==y.l) ma[x.r]=max(ma[x.r],x.rlen+y.llen);
llen=x.llen; rlen=y.rlen;
if (x.llen==x.siz) llen=x.llen+((y.l==x.r)?y.llen:);
if (y.rlen==y.siz) rlen=y.rlen+((y.l==x.r)?x.rlen:);
}
inline void G1() {
sum=siz-sum;
l^=,r^=; swap(ma[],ma[]);
}
inline void L1(int x) {
sum=x?siz:;
l=r=x; ma[x]=siz; ma[x^]=; llen=rlen=siz;
}
}T[N],RR;
int La[N],La1[N];
inline void updata(int node){
if (La[No]) { La[L(No)]=La[R(No)]=La[No];
T[L(No)].L1(La[No]&); La1[L(No)]=;
T[R(No)].L1(La[No]&); La1[R(No)]=; La[No]=; return;}
if (La1[No]) {
if (La[L(No)]) o(La[L(No)]),La1[L(No)]=; else La1[L(No)]^=;
if (La[R(No)]) o(La[R(No)]),La1[R(No)]=; else La1[R(No)]^=;
La1[No]=; T[L(No)].G1(); T[R(No)].G1(); return;}
}
void build(int node,int l,int r){
if (l==r) {
read(T[node].sum);
T[node].l=T[node].r=T[node].sum;
T[node].llen=T[node].rlen=T[node].siz=;
T[node].ma[T[node].sum]=;
return;
}
build(L(No),l,MID); build(R(No),MID+,r);
T[node].add(T[L(No)],T[R(No)]);
}
void change(int node,int l,int r,int L,int R,int col){
if (L<=l&&r<=R) { int XX=col&;
if (XX) { La1[No]=; La[No]=XX; T[No].L1(XX&);}
else { if (La[No]) o(La[No]),La1[No]=; else La1[No]^=; T[No].G1();
} return;
}
if (La[node]||La1[node]) updata(node);
if (R<=MID) change(L(No),l,MID,L,R,col); else
if (L> MID) change(R(No),MID+,r,L,R,col); else
change(L(No),l,MID,L,MID,col),change(R(No),MID+,r,MID+,R,col);
T[No].add(T[L(No)],T[R(No)]);
}
Node query(int node,int l,int r,int L,int R){
if (L<=l&&r<=R) return T[node];
if (La[node]||La1[node]) updata(node);
if (R<=MID) return query(L(No),l,MID,L,R);
if (L> MID) return query(R(No),MID+,r,L,R);
Node XX;
XX.add(query(L(No),l,MID,L,MID),query(R(No),MID+,r,MID+,R));
return XX;
}
void write(int x){
if (x<) {putchar(''+x);return;}write(x/); putchar(''+x%);
}
int n,m,op,X,Y;
int main () {
freopen("a.in","r",stdin);
read(n); read(m);
build(,,n);
while(m--) {
read(op); read(X); read(Y); X++; Y++;
switch (op){
case :change(,,n,X,Y,); break;
case :change(,,n,X,Y,); break;
case :change(,,n,X,Y,); break;
case :RR=query(,,n,X,Y);write(RR.sum);putchar('\n'); break;
case :RR=query(,,n,X,Y);write(RR.ma[]);putchar('\n'); break;
}
}
return ;
}
SCOI 2010 序列操作的更多相关文章
- 解题:SCOI 2010 序列操作
题面 线段树......模板题(雾? 然而两种标记会互相影响,必须保证每次只放一个(不然就不知道怎么放了),具体的影响就是: 翻转标记会使得覆盖标记一起翻转,下放的时候就是各种swap 覆盖标记会抹掉 ...
- SCOI2010 序列操作
2421 序列操作 http://codevs.cn/problem/2421/ 2010年省队选拔赛四川 题目描述 Description lxhgww最近收到了一个01序列,序列里面包含了n个 ...
- Python通用序列操作
1.序列概览 1.数据结构 序列.容器 Python中最基本的数据结构是序列,其有索引(从左到右第一个索引为0,从右到左第一个索引为-1). Python包含6中内建的序列: 列表 元组 字符串 Un ...
- 【BZOJ-2962】序列操作 线段树 + 区间卷积
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 678 Solved: 246[Submit][Status][Discuss] ...
- 【BZOJ-1858】序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1961 Solved: 991[Submit][Status ...
- bzoj 1858: [Scoi2010]序列操作
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...
- BZOJ 1858: [Scoi2010]序列操作( 线段树 )
略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...
- [bzoj]2962序列操作
[bzoj]2962序列操作 标签: 线段树 题目链接 题意 给你一串序列,要你维护三个操作: 1.区间加法 2.区间取相反数 3.区间内任意选k个数相乘的积 题解 第三个操作看起来一脸懵逼啊. 其实 ...
- bzoj 2962 序列操作
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 有一个长度为n的序列, ...
随机推荐
- codeforces 630C - Lucky Numbers 递推思路
630C - Lucky Numbers 题目大意: 给定数字位数,且这个数字只能由7和8组成,问有多少种组合的可能性 思路: 假设为1位,只有7和8:两位的时候,除了77,78,87,88之外还哇哦 ...
- 生成pdf
/** * 生成pdf * @param string $html 需要生成的内容 */ function pdf($html='<h1 style="color:red"& ...
- WireShark 使用
1.干货 Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直 ...
- Elasticsearch JAVA api搞定groupBy聚合
本文给出如何使用Elasticsearch的Java API做类似SQL的group by聚合.为了简单起见,只给出一级groupby即group by field1(而不涉及到多级,例如group ...
- java基础进阶一:String源码和String常量池
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...
- day6、Linux下如何找出7天以前的文件删除
有些时候,由于系统产生的日志文件,使服务器的磁盘空间紧张,所以怎么删除7天以前的日志文件及让系统只保留7天以内的日志文件 方法一 使用命令:find + |xargs + ls 命令方法:find / ...
- Django模型中value函数运用
values(*fields) 这个方法返回的是ValuesQuerySet,是QuerySet 的子类,也就是说,你可以用QuerySet里的方法. 需要注意的是,返回的不是list,不要直接当li ...
- Machine Learning - XV. Anomaly Detection异常检測 (Week 9)
http://blog.csdn.net/pipisorry/article/details/44783647 机器学习Machine Learning - Andrew NG courses学习笔记 ...
- ios应用程序国际化
1.程序名称国际化: 在Xcode中新建项目后,能够在project的info选项卡中找到Localization的项目,能够加入应用程序须要支持的国际语言. 回到项目中能够发如今InfoPlist. ...
- RPC-client异步收发核心细节?
通过上篇文章的介绍,知道了要实施微服务,首先要搞定RPC框架,RPC框架分为客户端部分与服务端部分. RPC-client的部分又分为: (1)序列化反序列化的部分(上图中的1.4) (2)发送字节流 ...