题目描述

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. javaScript函数参数

    <p>查找函数中参数最大的数</p> <p id="demo"></p> <script> x = findMax(1, ...

  2. java基础解析系列(十一)---equals、==和hashcode方法

    java基础解析系列(十一)---equals.==和hashcode方法 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系 ...

  3. UPDATE/INSERT用法研究

    UPDATE和INSERT语法相信大家都很熟悉,UPDATE的基本语法结构是 : UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 INSERT的基本语法是: INSERT ...

  4. NDK开发小记录 C++读取java层对象内容

    这是自己NDK开发得小记录,关于C++层读取java层传来的对象内容. 很简单的一个例子, 1.首先在java层定义了一个类NumList: public class NumList { public ...

  5. 阿里云部署Docker(4)----容器的使用

    通过上一节的学习,我们知道怎样执行docker容器,我们执行了一个普通的,一个后台的,我们还学习了几个指令: docker ps - Lists containers. docker logs - S ...

  6. kafka入门样例 for java

    1,生产者 import java.util.Properties; import kafka.javaapi.producer.Producer; import kafka.producer.Key ...

  7. Vue深度学习(6)- 组件

    使用组件 在Vue中,可以用 Vue.extend() 创建一个组件构造器: var MyComponent = Vue.extend({ template:'..........' //选项 }) ...

  8. DocFX生成PDF文档

    使用DocFX生成PDF文档,将在线文档转换为PDF离线文档. 关于DocFX的简单介绍使用DocFX生成文档 使用docfx 命令 1.下载 https://github.com/dotnet/do ...

  9. 在Azure Container Service创建Kubernetes(k8s)群集运行ASP.NET Core跨平台应用程序

    引子 在此前的一篇文章中,我介绍了如何在本地docker环境中运行ASP.NET Core跨平台应用程序(http://www.cnblogs.com/chenxizhang/p/7148657.ht ...

  10. OS X第三方类库管理工具cocoapods入门

    一.简介 什么是cocoapods?--是OS X和iOS下一个第三方类库管理工具.通过cocoapods,可以为项目添加"Pods"依赖库,并且管理其版本. cocoapods好 ...