题目描述

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. 下拉菜单被挡住了,DIV置于最底层的方法

    网站常会用到一些 下拉菜单,,幻灯片,,,飘浮广告等. 但经常会发现.幻灯片会挡住下拉菜单或者飘浮广告等.解决办法有下 第一,可将幻灯片所在DIV 置于最底层.添加CSS如下 style=" ...

  2. “IAsyncOperation<StorageFile>”不包含“GetAwaiter”的定义

    错误 CS4036 "IAsyncOperation<StorageFile>"不包含"GetAwaiter"的定义,并且找不到可接受类型为&quo ...

  3. 双向bfs-八数码问题

    [八数码][1] [1]: https://www.luogu.org/problem/show?pid=1379 其实除了搜索恶心一点,好像也没什么提高+的 bfs搜的是状态. 双向bfs同时从起点 ...

  4. Android数据绑定技二,企业级开发

    PS:上一篇文章写了Databinding的简单使用,写了一个绑定textview的示例,和绑定的一些用法,估计有的人会说,之前的写的好好的,为什么要数据绑定这样的写法呢,没办法,社会在进步,当然是怎 ...

  5. 使用oracle DB_LINK的一个注意点

    今天使用db_link的时候遇到了个有趣的问题,和大家分享一下; 环境:Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bi ...

  6. quzrtz的使用

    Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便. 一.核心概念 1.Job 表示一个工作,要执行的具体内容,此接口只有一个方法 void execute(JobExecuti ...

  7. 诡异的 &quot;password取回&quot; 邮件问题

    大部分系统中都有"找回password"的功能,我们的平台也做了此功能,用户可通过 短信,邮件 找回password. 当中对于邮件找回password的方式遇到奇特的问题.记录下 ...

  8. Hibernate的load()和get()区别

    最近在用Hibernate的时候发现一个问题:比如我们从数据库获得一个对象时,使用session.get()方法还是session.load()?  两种方法在获得一个实体对象时是有区别的,在查询性能 ...

  9. Spring学习笔记(三)之装配Bean

    除了组件扫描与自动装配之外还有基于Java代码的装配与基于XML的装配. 有一些场景是我们不能用自动装配的,比如我们要给第三方库中的组件装配到我们的应用中,这时自动装配无效,因为自动装配只能扫描本应用 ...

  10. java基础数据类型包装类

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...