题目描述

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 序列操作的更多相关文章

  1. 解题:SCOI 2010 序列操作

    题面 线段树......模板题(雾? 然而两种标记会互相影响,必须保证每次只放一个(不然就不知道怎么放了),具体的影响就是: 翻转标记会使得覆盖标记一起翻转,下放的时候就是各种swap 覆盖标记会抹掉 ...

  2. SCOI2010 序列操作

    2421 序列操作 http://codevs.cn/problem/2421/ 2010年省队选拔赛四川   题目描述 Description lxhgww最近收到了一个01序列,序列里面包含了n个 ...

  3. Python通用序列操作

    1.序列概览 1.数据结构 序列.容器 Python中最基本的数据结构是序列,其有索引(从左到右第一个索引为0,从右到左第一个索引为-1). Python包含6中内建的序列: 列表 元组 字符串 Un ...

  4. 【BZOJ-2962】序列操作 线段树 + 区间卷积

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 678  Solved: 246[Submit][Status][Discuss] ...

  5. 【BZOJ-1858】序列操作 线段树

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1961  Solved: 991[Submit][Status ...

  6. bzoj 1858: [Scoi2010]序列操作

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MB 线段树,对于每个区间需要分别维护左右和中间的1和0连续个数,并在op=4时特殊 ...

  7. BZOJ 1858: [Scoi2010]序列操作( 线段树 )

    略恶心的线段树...不过只要弄清楚了AC应该不难.... ---------------------------------------------------------------- #inclu ...

  8. [bzoj]2962序列操作

    [bzoj]2962序列操作 标签: 线段树 题目链接 题意 给你一串序列,要你维护三个操作: 1.区间加法 2.区间取相反数 3.区间内任意选k个数相乘的积 题解 第三个操作看起来一脸懵逼啊. 其实 ...

  9. bzoj 2962 序列操作

    2962: 序列操作 Time Limit: 50 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 有一个长度为n的序列, ...

随机推荐

  1. HDU 2795 Billboard 线段树,区间最大值,单点更新

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. mysql事务使用 超简单

    MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID事务.行级锁.并发 3.Berkeley DB: ...

  3. staticmethod、classmethod的使用

    staticmethod 首先要明白两个概念 绑定方法:但凡是定义在类的内部,并且没有被任何装饰器修饰过的方法,就是绑定方法,并且有自动传值功能.类直接调用该方法时,改方法叫做类的函数属性:对象在调用 ...

  4. UWP 实现App多语言为所欲为切换

    为所欲为,嗯 话不多说,先看效果吧(事先说明,我的方法不是最好的,但是我用着最有效.) [吐槽一下博客园上传的图片,我的App敲鸡漂亮滴,自带亚克力效果,怎么图片上传上来这么多的噪点啊.] [ 商店地 ...

  5. SQL Server Profiler的使用

    最近一个项目,使用微软的Entity Framework的ORM框架的项目,部署到现场后,出现了系统缓慢,多个客户端的内存溢出崩溃的问题. 打开了SQL Server Profiler排查,发现有全表 ...

  6. 防止UI穿透操作到游戏场景

    #if UNITY_EDITOR || UNITY_STANDALONE_WIN if (EventSystem.current.IsPointerOverGameObject()) { return ...

  7. svn服务器的搭建与使用一

    转载出处 Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址: ht ...

  8. Nginx限速模块初探

    Nginx限速模块分为哪几种?按请求速率限速的burst和nodelay参数是什么意思?漏桶算法和令牌桶算法究竟有什么不同?本文将带你一探究竟.我们会通过一些简单的示例展示Nginx限速模块是如何工作 ...

  9. FreeCAD源码阅读笔记

    本文目标在于记录在FreeCAD源码阅读中了解到的一些东西. FreeCAD编译 FreeCAD源码的编译最好使用官方提供的LibPack,否则第三方库难以找全,找到之后还需要自己编译,此外还不知道C ...

  10. get和post提交数据的差别

    form表单提交,默认method = "get",所以你在提交数据的时候,最好将此參数指定为method = "post",否则你在提交大数据的时候,可能会出 ...