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

----------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
 
#define rep( i , n ) for( int i = 0 ; i < n ; i++ )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define L( x ) ( ( x ) << 1 )
#define R( x ) ( L( x ) ^ 1 )
#define LC L( x ) , l , m
#define RC R( x ) , m + 1 , r
#define X x , l , r
#define XX int x , int l , int r
#define M( l , r ) ( ( l + r ) >> 1 )
#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
 
using namespace std;
 
const int maxn = 100000 + 5;
const int maxnode = 270000;
 
int n , seq[ maxn ];
 
struct Node {
int sum , l_cnt[ 2 ] , r_cnt[ 2 ] , cnt[ 2 ] , set;
bool rev;
Node() {
set = -1;
rev = false;
}
};
 
Node tree[ maxnode ];
 
int L , R , op;
 
void maintain( XX ) {
Node &o = tree[ x ];
if( r > l ) {
Node &lc = tree[ L( x ) ] , &rc = tree[ R( x ) ];
int m = M( l , r );
   o.sum = lc.sum + rc.sum;
   rep( i , 2 ) {
       o.cnt[ i ] = max( max( lc.cnt[ i ] , rc.cnt[ i ] ) , lc.r_cnt[ i ] + rc.l_cnt[ i ] );
       if( lc.l_cnt[ i ] == m - l + 1 )
           o.l_cnt[ i ] = lc.l_cnt[ i ] + rc.l_cnt[ i ];
       else
   o.l_cnt[ i ] = lc.l_cnt[ i ];
       if( rc.r_cnt[ i ] == r - m )
           o.r_cnt[ i ] = rc.r_cnt[ i ] + lc.r_cnt[ i ];
       else
   o.r_cnt[ i ] = rc.r_cnt[ i ];
   }
}
if( o.set != -1 ) {
o.sum = o.set ? r - l + 1 : 0;
o.cnt[ 1 ] = o.l_cnt[ 1 ] = o.r_cnt[ 1 ] = o.sum;
o.cnt[ 0 ] = o.l_cnt[ 0 ] = o.r_cnt[ 0 ] = r - l + 1 - o.sum;
}
if( o.rev ) {
o.sum = r - l + 1 - o.sum;
swap( o.l_cnt[ 0 ] , o.l_cnt[ 1 ] );
swap( o.r_cnt[ 0 ] , o.r_cnt[ 1 ] );
swap( o.cnt[ 0 ] , o.cnt[ 1 ] );
}
}
 
void pushdown( XX ) {
Node &o = tree[ x ] , &lc = tree[ L( x ) ] , &rc = tree[ R( x ) ];
if( o.set != -1 ) {
lc.set = rc.set = o.set;
lc.rev = rc.rev = false;
o.set = -1;
}
if( o.rev ) {
lc.rev ^= 1;
rc.rev ^= 1;
o.rev =false;
}
}
 
void update( XX ) {
Node &o = tree[ x ];
if( L <= l && r <= R ) {
if( op == 2 ) {
if( o.set != -1 ) o.set ^= 1;
   else o.rev ^= 1;
} else {
   o.set = op;
   o.rev = false;
}  
} else {
int m = M( l , r );
   pushdown( X );
   maintain( LC );
   maintain( RC );
if( L <= m ) update( LC );
if( m < R ) update( RC );
}
maintain( X );
}
 
Node merge( int l , int r , Node lc , Node rc ) {
Node o;
int m = M( l , r );
o.sum = lc.sum + rc.sum;
rep( i , 2 ) {
   o.cnt[ i ] = max( max( lc.cnt[ i ] , rc.cnt[ i ] ) , lc.r_cnt[ i ] + rc.l_cnt[ i ] );
     if( lc.l_cnt[ i ] == m - l + 1 )
   o.l_cnt[ i ] = lc.l_cnt[ i ] + rc.l_cnt[ i ];
else
o.l_cnt[ i ] = lc.l_cnt[ i ];
if( rc.r_cnt[ i ] == r - m )
   o.r_cnt[ i ] = rc.r_cnt[ i ] + lc.r_cnt[ i ];
else
o.r_cnt[ i ] = rc.r_cnt[ i ];
}
return o;
}
 
Node query( XX ) {
Node &o = tree[ x ];
if( L <= l && r <= R )
return o;
int m = M( l , r );
pushdown( X );
maintain( LC );
maintain( RC );
if( R <= m ) return query( LC );
else if( m < L ) return query( RC );
else return merge( l , r , query( LC ) , query( RC ) );
 
void build( XX ) {
Node &o = tree[ x ];
if( l == r ) {
o.set =seq[ l ];
} else {
int m = M( l , r );
build( LC );
build( RC );
}
maintain( X );
}
 
int main() {
freopen( "test.in" , "r" , stdin );
int m;
cin >> n >> m;
Rep( i , n )
   scanf( "%d" , seq + i );
build( 1 , 1 , n );
    while( m-- ) {
    scanf( "%d%d%d" , &op , &L , &R );
    L++ , R++;
    if( op < 3 ) update( 1 , 1 , n );
     else {
    Node o = query( 1 , 1 , n );
    printf( "%d\n" , op == 3 ? o.sum : o.cnt[ 1 ] );
    }
 
    }
    
return 0;
}

----------------------------------------------------------------

1858: [Scoi2010]序列操作

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1425  Solved: 737
[Submit][Status][Discuss]

Description

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都需要给出回答,聪明的程序员们,你们能帮助他吗?

Input

输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目 第二行包括n个数,表示序列的初始状态 接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b

Output

对于每一个询问操作,输出一行,包括1个数,表示其对应的答案

Sample Input

10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9

Sample Output

5
2
6
5

HINT

对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000

Source

BZOJ 1858: [Scoi2010]序列操作( 线段树 )的更多相关文章

  1. (WAWAWAWAWAWA) BZOJ 1858: [Scoi2010]序列操作

    二次联通门 : BZOJ 1858: [Scoi2010]序列操作 /* BZOJ 1858: [Scoi2010]序列操作 已经... 没有什么好怕的的了... 16K的代码... 调个MMP啊.. ...

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

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

  3. bzoj1858[Scoi2010]序列操作 线段树

    1858: [Scoi2010]序列操作 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 3079  Solved: 1475[Submit][Statu ...

  4. 【bzoj1858】[Scoi2010]序列操作 线段树区间合并

    题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...

  5. Luogu P2572 [SCOI2010]序列操作 线段树。。

    咕咕了...于是借鉴了小粉兔的做法ORZ... 其实就是维护最大子段和的线段树,但上面又多了一些操作....QWQ 维护8个信息:1/0的个数(sum),左/右边起1/0的最长长度(ls,rs),整段 ...

  6. bzoj1858 [Scoi2010]序列操作——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1858 线段树...调了一个上午...(后面带 // 的都是改出来的) lazy 标记的下放好 ...

  7. bzoj 1858: [Scoi2010]序列操作 || 洛谷 P2572

    记一下:线段树占空间是$2^{ceil(log2(n))+1}$ 这个就是一个线段树区间操作题,各种标记的设置.转移都很明确,只要熟悉这类题应该说是没有什么难度的. 由于对某区间set之后该区间原先待 ...

  8. 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树

    正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...

  9. [SCOI2010]序列操作 线段树

    ---题面--- 题解: 在考场上打的这道题,出人意料的很快就打完了?! 直接用线段树,维护几个东西: 1,lazy标记 : 表示区间赋值 2,mark标记:表示区间翻转 3,l1:前缀最长连续的1的 ...

随机推荐

  1. Lucence.Net学习+盘古分词

    创建索引库          //读取文件,存储到索引库           public string CreateDatebase()         {         //获取索引库的路径   ...

  2. ThinkPHP常量参考

    常用常量 APP_NAME 当前项目名称 APP_PATH 当前项目路径 GROUP_NAME 当前分组名称 MODULE_NAME 当前Action模块名称 ACTION_NAME 当前操作的名称 ...

  3. 神奇的魔法数字0x61c88647

    来源JDK源码,产生的数字分布很均匀 用法代码如下. # -*- coding: utf-8 -*- HASH_INCREMENT = 0x61c88647 def magic_hash(n): fo ...

  4. 解决spark运行中failed to locate the winutils binary in the hadoop binary path的问题

    1.下载hadoop-common-2.2.0-bin并解压到某个目录 https://github.com/srccodes/hadoop-common-2.2.0-bin 2.设置hadoop.h ...

  5. ASP.NET MVC进阶之路:深入理解依赖注入(DI)和控制反转(IOC)

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  6. sql语法复习:增删查改,各种数据库对象创建和函数使用

    推荐工具:机子配置较低的话,可以装Gsql这个工具获得sql执行环境(可作为手册查看内置数据类型 函数和存储过程等) --之前数据库的东西接触不多,虽然基本的语法是了解,但不是很熟悉--最近项目一直在 ...

  7. HDU 2178 猜数字

    题解:设猜到的最大的数是h,在1到h间,你最多只要猜log2(h)+1(取整)次,所以易知==>h=2^m-1.即猜m次,能猜到的最大的数为2^m-1. #include <cstdio& ...

  8. BZOJ 1062

    program candy bzoj1062; ; maxm=; maxn=; var n,len,m,i,p,t,l,r,c,d,q:longint; s:..,..maxn,..maxm] of ...

  9. hdoj 1269 迷宫城堡(强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269 思路分析:该问题要求判断是否每两个房间都可以相互到达,即求该有向图中的所有点是否只构成一个强连通 ...

  10. 集团财务分析BI项目中的财务系统环境

    我国集团化经营模式起步较晚,集团管控模式及管控力度各异,集团范围内财务信息化水平及统一程度不尽相同,因此在实施集团财务分析一类的BI商业智能项目的过程中,在不同的集团之间遇到的财务系统及核算数据环境也 ...