比较烦的线段树

首先询问3很弱智不说,

询问4以前做过类似的,好像是USACO月赛hotel那题类似,维护lmax,rmax,max三个域就可以了

操作0,操作1也很简单,仔细考虑一下就知道也是可以lazy tag的

重点是操作2,好像数据结构题中翻转总是一个难点

由于翻转影响对询问4影响较大(对询问3基本没什么影响)

我们考虑这次维护六个域lmax0,rmax0,max0,lmax1,rmax1 max1 分别表示在区间内0和1从左起最多连续几个,从右起最多连续几个,区间内最多连续几个

然后我们来考虑操作,首先难想到维护rev域表示区间是否翻转,lazy表示0表示全0,1表示全1,-1表示没有进行覆盖操作

操作0,1对操作2有强制性,只要执行操作0,1,就一定可以直接覆盖之前的操作

然后执行取反操作的时候,如果lazy<>-1 那么对lazy取反(0-->1 1-->0) 否则再对rev取反

 type node=record
       l,r,lm1,rm1,m1,lm0,rm0,m0,sum:longint;
     end; var tree:array[..] of node;
    lazy,a:array[..] of integer;
    rev:array[..] of boolean;
    ch,i,n,m,x,y:longint; function max(a,b:longint):longint;
  begin
    if a>b then exit(a) else exit(b);
  end; function min(a,b:longint):longint;
  begin
    if a>b then exit(b) else exit(a);
  end; procedure swap(var a,b:longint);
  var c:longint;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; procedure fill1(i:longint);
  var l,r:longint;
  begin
    l:=tree[i].l;
    r:=tree[i].r;
    tree[i].sum:=r-l+;
    tree[i].lm1:=r-l+;
    tree[i].rm1:=r-l+;
    tree[i].m1:=r-l+;
    tree[i].lm0:=;
    tree[i].rm0:=;
    tree[i].m0:=;
  end; procedure fill0(i:longint);
  var l,r:longint;
  begin
    l:=tree[i].l;
    r:=tree[i].r;
    tree[i].sum:=;
    tree[i].lm0:=r-l+;
    tree[i].rm0:=r-l+;
    tree[i].m0:=r-l+;
    tree[i].lm1:=;
    tree[i].rm1:=;
    tree[i].m1:=;
  end; procedure change(i:longint);
  var l,r:longint;
  begin
    l:=tree[i].l;
    r:=tree[i].r;
    tree[i].sum:=(r-l+)-tree[i].sum;
    swap(tree[i].m1,tree[i].m0);
    swap(tree[i].lm1,tree[i].lm0);
    swap(tree[i].rm1,tree[i].rm0);
  end; procedure update(i:longint);   //由下向上更新
  var l,r,m,p:longint;
  begin
    l:=tree[i].l;
    r:=tree[i].r;
    m:=(l+r) shr ;
    tree[i].sum:=tree[i*].sum+tree[i*+].sum;
//
    tree[i].lm1:=tree[i*].lm1;
    if tree[i*].lm1=m-l+ then
      tree[i].lm1:=tree[i].lm1+tree[i*+].lm1;     tree[i].rm1:=tree[i*+].rm1;
    if tree[i*+].rm1=r-m then
      tree[i].rm1:=tree[i].rm1+tree[i*].rm1;     tree[i].m1:=max(tree[i].lm1,tree[i].rm1);
    p:=max(tree[i*].rm1+tree[i*+].lm1,max(tree[i*].m1,tree[i*+].m1));
    tree[i].m1:=max(p,tree[i].m1);
//
    tree[i].lm0:=tree[i*].lm0;
    if tree[i*].lm0=m-l+ then
      tree[i].lm0:=tree[i].lm0+tree[i*+].lm0;     tree[i].rm0:=tree[i*+].rm0;
    if tree[i*+].rm0=r-m then
      tree[i].rm0:=tree[i].rm0+tree[i*].rm0;     tree[i].m0:=max(tree[i].lm0,tree[i].rm0);
    p:=max(tree[i*].rm0+tree[i*+].lm0,max(tree[i*].m0,tree[i*+].m0));
    tree[i].m0:=max(p,tree[i].m0);
  end; procedure pushdown(i:longint);   //传递标记
  begin
    if lazy[i]<>- then
    begin
      lazy[i*]:=lazy[i];
      lazy[i*+]:=lazy[i];
      if lazy[i]= then
      begin
        fill1(i*);
        fill1(i*+);
      end
      else begin
        fill0(i*);
        fill0(i*+);
      end;
      lazy[i]:=-;
      rev[i]:=false;  
    end;
    if rev[i] then
    begin
      if lazy[i*]<>- then lazy[i*]:=-lazy[i*]
      else rev[i*]:=not rev[i*];
      if lazy[i*+]<>- then lazy[i*+]:=-lazy[i*+]
      else rev[i*+]:=not rev[i*+];
      change(i*+);
      change(i*);
      rev[i]:=false;
    end;
  end; procedure build(i,l,r:longint);
  var m:longint;
  begin
    tree[i].l:=l;
    tree[i].r:=r;
    lazy[i]:=-;
    if l=r then
    begin
      tree[i].sum:=a[l];
      if a[l]= then
      begin
        tree[i].lm1:=;
        tree[i].rm1:=;
        tree[i].m1:=;
      end
      else begin
        tree[i].lm0:=;
        tree[i].rm0:=;
        tree[i].m0:=;
      end;
    end
    else begin
      m:=(l+r) shr ;
      build(i*,l,m);
      build(i*+,m+,r);
      update(i);
    end;
  end; procedure work(i,l,r:longint);
  var m:longint;
  begin
    if (x<=l) and (y>=r) then
    begin
      if rev[i]=true then rev[i]:=false;
      lazy[i]:=ch;
      if ch= then fill1(i)
      else fill0(i);
    end
    else begin
      if (lazy[i]<>-) or (rev[i]) then pushdown(i);
      m:=(l+r) shr ;
      if x<=m then work(i*,l,m);
      if y>=m+ then work(i*+,m+,r);
      update(i);
    end;
  end; procedure reverse(i,l,r:longint);
  var m:longint;
  begin
    if (x<=l) and (y>=r) then
    begin
      if lazy[i]<>- then lazy[i]:=-lazy[i]
      else rev[i]:=not rev[i];
      change(i);
    end
    else begin
      if (lazy[i]<>-) or rev[i] then pushdown(i);
      m:=(l+r) shr ;
      if x<=m then reverse(i*,l,m);
      if y>=m+ then reverse(i*+,m+,r);
      update(i);
    end;
  end; function asksum(i,l,r:longint):longint;
  var m,t:longint;
  begin
    if (x<=l) and (y>=r) then exit(tree[i].sum)
    else begin
      if (lazy[i]<>-) or rev[i] then pushdown(i);
      m:=(l+r) shr ;
      t:=;
      if (x<=m) then t:=t+asksum(i*,l,m);
      if y>=m+ then t:=t+asksum(i*+,m+,r);
      update(i);
      exit(t);
    end;
  end; function askmax(i,l,r:longint):longint;
  var m,t,t1,t2:longint;
  begin
    if (x<=l) and (y>=r) then exit(tree[i].m1)
    else begin
      if (lazy[i]<>-) or rev[i] then pushdown(i);
      m:=(l+r) shr ;
      t1:=;
      t2:=;
      t:=;
      if (x<=m) then t1:=askmax(i*,l,m);
      if y>=m+ then t2:=askmax(i*+,m+,r);
      if (x<=m) and (y>=m+) then t:=min(tree[i*].rm1,m-x+)+min(tree[i*+].lm1,y-m); //注意不能少考虑这种情况
      t:=max(t,max(t1,t2));
      update(i);
      exit(t);
    end;
  end; begin
  readln(n,m);
  for i:= to n do
    read(a[i]);
  build(,,n);   //初始化
  for i:= to m do
  begin
    readln(ch,x,y);
    inc(x);
    inc(y);
    if ch= then
      work(,,n)
    else if ch= then
      work(,,n)
    else if ch= then
      reverse(,,n)
    else if ch= then
      writeln(asksum(,,n))
    else if ch= then
      writeln(askmax(,,n));
  end;
end.

bzoj1858的更多相关文章

  1. 【BZOJ1858】序列操作(线段树)

    [BZOJ1858]序列操作(线段树) 题面 BZOJ 题解 这题思路很简单,细节很烦,很码 维护区间翻转和区间赋值标记 当打到区间赋值标记时直接覆盖掉翻转标记 下放标记的时候先放赋值标记再放翻转标记 ...

  2. scoi2010&&bzoj1858序列操作

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

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

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

  4. BZOJ1858[Scoi2010]序列操作 题解

    题目大意: 有一个01序列,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0:1 a b 把[a, b]区间内的所有数全变成1:2 a b 把[a,b]区间 ...

  5. bzoj1858: [Scoi2010]序列操作

    lazy-tag线段树. #include<cstdio> #include<algorithm> #include<cstring> using namespac ...

  6. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

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

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

  8. [待码][BZOJ1858]SCOI2010序列操作 jzyzoj1655

    待码的线段树.....太长了看上去不是很想写 [ 什么破理由啊摔,不要脸 ] 嗯先水几道再写

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

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

随机推荐

  1. SQL Server 2012 数据库各个版本功能对比

    作为这篇SQL SERVER 2008数据库各版本功能对比 的姊妹篇,就写点SQL Server 2012 各个版本的区别以及物理以及逻辑上的限制. 个部分来分http://technet.micro ...

  2. ACM/ICPC ZOJ1009-Enigma 解题代码

    #include <iostream> #include <string> using namespace std; int main() { int strwide; cin ...

  3. 开源织梦(dedecms)快速搬家图文教程

    前段时间在seowhy班级群里,一个同学问织梦程序怎么搬家,好多人都遇到过这样的问题,不知道怎么去处理,今天小编分享一个简单的方法,帮大家快速搬家织梦. 好了,废话留到最后再说,看下面方法: 1. 登 ...

  4. weblogic9.2重置密码

    1.删除DefaultAuthenticatorInit.ldift 2.执行命令:java -cp /home/weblogic/bea/weblogic92/server/lib/weblogic ...

  5. 关于MDCSwipeToChooseView的应用

    本人因为项目中某个页面的功能需要,用到了MDCSwipeToChooseView,就在网上查阅了相关的资料,资源有很多,但应该都是同一个人上传的,code4还有git上都有,但下载demo下来后运行不 ...

  6. CCPC网赛,HDU_5832 A water problem

    Problem Description           Two planets named Haha and Xixi in the universe and they were created ...

  7. C++类继承内存布局(三)

    参考:http://blog.csdn.net/jiangyi711/article/details/4890889# (三)成员函数 类X中每一个非静态成员函数都会接受一个特殊的隐藏参数——this ...

  8. Javascript数组的indexOf()、lastIndexOf()方法

    在javascript数组中提供了两个方法来对数组进行查找,这两个方法分别为indexOf(),lastIndexOf(). 这两个方法都有两个参数,第一个参数为需要查找的项,第二个参数则是查找的起始 ...

  9. vi 编辑器的使用

    1)    vi的自动对齐功能   我从window的网页上拷贝了一段代码到vi中,结果是不对齐的.见下图 此时为了对齐,我的做法是: ESC-v  进入视图模式,然后全选 再然后直接按 = 号. 然 ...

  10. The CircuitCalculator.com Blog a blog with live web calculators Home About Policies Contact PCB

    PCB Trace Width Calculator 转载自:CircuitCalculator.com 关键词: PCB,Layout,电流,导线宽度. This Javascript web ca ...