• bzoj1858


    比较烦的线段树

    首先询问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取反

      1 type node=record
      2        l,r,lm1,rm1,m1,lm0,rm0,m0,sum:longint;
      3      end;
      4 
      5 var tree:array[0..400010] of node;
      6     lazy,a:array[0..400010] of integer;
      7     rev:array[0..400010] of boolean;
      8     ch,i,n,m,x,y:longint;
      9 
     10 function max(a,b:longint):longint;
     11   begin
     12     if a>b then exit(a) else exit(b);
     13   end;
     14 
     15 function min(a,b:longint):longint;
     16   begin
     17     if a>b then exit(b) else exit(a);
     18   end;
     19 
     20 procedure swap(var a,b:longint);
     21   var c:longint;
     22   begin
     23     c:=a;
     24     a:=b;
     25     b:=c;
     26   end;
     27 
     28 procedure fill1(i:longint);
     29   var l,r:longint;
     30   begin
     31     l:=tree[i].l;
     32     r:=tree[i].r;
     33     tree[i].sum:=r-l+1;
     34     tree[i].lm1:=r-l+1;
     35     tree[i].rm1:=r-l+1;
     36     tree[i].m1:=r-l+1;
     37     tree[i].lm0:=0;
     38     tree[i].rm0:=0;
     39     tree[i].m0:=0;
     40   end;
     41 
     42 procedure fill0(i:longint);
     43   var l,r:longint;
     44   begin
     45     l:=tree[i].l;
     46     r:=tree[i].r;
     47     tree[i].sum:=0;
     48     tree[i].lm0:=r-l+1;
     49     tree[i].rm0:=r-l+1;
     50     tree[i].m0:=r-l+1;
     51     tree[i].lm1:=0;
     52     tree[i].rm1:=0;
     53     tree[i].m1:=0;
     54   end;
     55 
     56 procedure change(i:longint);
     57   var l,r:longint;
     58   begin
     59     l:=tree[i].l;
     60     r:=tree[i].r;
     61     tree[i].sum:=(r-l+1)-tree[i].sum;
     62     swap(tree[i].m1,tree[i].m0);
     63     swap(tree[i].lm1,tree[i].lm0);
     64     swap(tree[i].rm1,tree[i].rm0);
     65   end;
     66 
     67 procedure update(i:longint);   //由下向上更新
     68   var l,r,m,p:longint;
     69   begin
     70     l:=tree[i].l;
     71     r:=tree[i].r;
     72     m:=(l+r) shr 1;
     73     tree[i].sum:=tree[i*2].sum+tree[i*2+1].sum;
     74 // 1
     75     tree[i].lm1:=tree[i*2].lm1;
     76     if tree[i*2].lm1=m-l+1 then
     77       tree[i].lm1:=tree[i].lm1+tree[i*2+1].lm1;
     78 
     79     tree[i].rm1:=tree[i*2+1].rm1;
     80     if tree[i*2+1].rm1=r-m then
     81       tree[i].rm1:=tree[i].rm1+tree[i*2].rm1;
     82 
     83     tree[i].m1:=max(tree[i].lm1,tree[i].rm1);
     84     p:=max(tree[i*2].rm1+tree[i*2+1].lm1,max(tree[i*2].m1,tree[i*2+1].m1));
     85     tree[i].m1:=max(p,tree[i].m1);
     86 // 0
     87     tree[i].lm0:=tree[i*2].lm0;
     88     if tree[i*2].lm0=m-l+1 then
     89       tree[i].lm0:=tree[i].lm0+tree[i*2+1].lm0;
     90 
     91     tree[i].rm0:=tree[i*2+1].rm0;
     92     if tree[i*2+1].rm0=r-m then
     93       tree[i].rm0:=tree[i].rm0+tree[i*2].rm0;
     94 
     95     tree[i].m0:=max(tree[i].lm0,tree[i].rm0);
     96     p:=max(tree[i*2].rm0+tree[i*2+1].lm0,max(tree[i*2].m0,tree[i*2+1].m0));
     97     tree[i].m0:=max(p,tree[i].m0);
     98   end;
     99 
    100 procedure pushdown(i:longint);   //传递标记
    101   begin
    102     if lazy[i]<>-1 then
    103     begin
    104       lazy[i*2]:=lazy[i];
    105       lazy[i*2+1]:=lazy[i];
    106       if lazy[i]=1 then
    107       begin
    108         fill1(i*2);
    109         fill1(i*2+1);
    110       end
    111       else begin
    112         fill0(i*2);
    113         fill0(i*2+1);
    114       end;
    115       lazy[i]:=-1;
    116       rev[i]:=false;  
    117     end;
    118     if rev[i] then
    119     begin
    120       if lazy[i*2]<>-1 then lazy[i*2]:=1-lazy[i*2]
    121       else rev[i*2]:=not rev[i*2];
    122       if lazy[i*2+1]<>-1 then lazy[i*2+1]:=1-lazy[i*2+1]
    123       else rev[i*2+1]:=not rev[i*2+1];
    124       change(i*2+1);
    125       change(i*2);
    126       rev[i]:=false;
    127     end;
    128   end;
    129 
    130 procedure build(i,l,r:longint);
    131   var m:longint;
    132   begin
    133     tree[i].l:=l;
    134     tree[i].r:=r;
    135     lazy[i]:=-1;
    136     if l=r then
    137     begin
    138       tree[i].sum:=a[l];
    139       if a[l]=1 then
    140       begin
    141         tree[i].lm1:=1;
    142         tree[i].rm1:=1;
    143         tree[i].m1:=1;
    144       end
    145       else begin
    146         tree[i].lm0:=1;
    147         tree[i].rm0:=1;
    148         tree[i].m0:=1;
    149       end;
    150     end
    151     else begin
    152       m:=(l+r) shr 1;
    153       build(i*2,l,m);
    154       build(i*2+1,m+1,r);
    155       update(i);
    156     end;
    157   end;
    158 
    159 procedure work(i,l,r:longint);
    160   var m:longint;
    161   begin
    162     if (x<=l) and (y>=r) then
    163     begin
    164       if rev[i]=true then rev[i]:=false;
    165       lazy[i]:=ch;
    166       if ch=1 then fill1(i)
    167       else fill0(i);
    168     end
    169     else begin
    170       if (lazy[i]<>-1) or (rev[i]) then pushdown(i);
    171       m:=(l+r) shr 1;
    172       if x<=m then work(i*2,l,m);
    173       if y>=m+1 then work(i*2+1,m+1,r);
    174       update(i);
    175     end;
    176   end;
    177 
    178 procedure reverse(i,l,r:longint);
    179   var m:longint;
    180   begin
    181     if (x<=l) and (y>=r) then
    182     begin
    183       if lazy[i]<>-1 then lazy[i]:=1-lazy[i]
    184       else rev[i]:=not rev[i];
    185       change(i);
    186     end
    187     else begin
    188       if (lazy[i]<>-1) or rev[i] then pushdown(i);
    189       m:=(l+r) shr 1;
    190       if x<=m then reverse(i*2,l,m);
    191       if y>=m+1 then reverse(i*2+1,m+1,r);
    192       update(i);
    193     end;
    194   end;
    195 
    196 function asksum(i,l,r:longint):longint;
    197   var m,t:longint;
    198   begin
    199     if (x<=l) and (y>=r) then exit(tree[i].sum)
    200     else begin
    201       if (lazy[i]<>-1) or rev[i] then pushdown(i);
    202       m:=(l+r) shr 1;
    203       t:=0;
    204       if (x<=m) then t:=t+asksum(i*2,l,m);
    205       if y>=m+1 then t:=t+asksum(i*2+1,m+1,r);
    206       update(i);
    207       exit(t);
    208     end;
    209   end;
    210 
    211 function askmax(i,l,r:longint):longint;
    212   var m,t,t1,t2:longint;
    213   begin
    214     if (x<=l) and (y>=r) then exit(tree[i].m1)
    215     else begin
    216       if (lazy[i]<>-1) or rev[i] then pushdown(i);
    217       m:=(l+r) shr 1;
    218       t1:=0;
    219       t2:=0;
    220       t:=0;
    221       if (x<=m) then t1:=askmax(i*2,l,m);
    222       if y>=m+1 then t2:=askmax(i*2+1,m+1,r);
    223       if (x<=m) and (y>=m+1) then t:=min(tree[i*2].rm1,m-x+1)+min(tree[i*2+1].lm1,y-m); //注意不能少考虑这种情况
    224       t:=max(t,max(t1,t2));
    225       update(i);
    226       exit(t);
    227     end;
    228   end;
    229 
    230 begin
    231   readln(n,m);
    232   for i:=1 to n do
    233     read(a[i]);
    234   build(1,1,n);   //初始化
    235   for i:=1 to m do
    236   begin
    237     readln(ch,x,y);
    238     inc(x);
    239     inc(y);
    240     if ch=0 then
    241       work(1,1,n)
    242     else if ch=1 then
    243       work(1,1,n)
    244     else if ch=2 then
    245       reverse(1,1,n)
    246     else if ch=3 then
    247       writeln(asksum(1,1,n))
    248     else if ch=4 then
    249       writeln(askmax(1,1,n));
    250   end;
    251 end.
    View Code
  • 相关阅读:
    继承LIst 的类JSON序列化,无法序列化属性的问题
    C#深入学习:泛型修饰符in,out、逆变委托类型和协变委托类型
    12.Java web--过滤器与监听器
    11.Java web—servlet
    10.Java web—JavaBean
    9.Java web—JSP内置对象
    8.Java web—JSP基本语法
    Ubuntu 插入鼠标自动禁用触控板
    Ubuntu安装VLC播放器
    Ubuntu快捷键
  • 原文地址:https://www.cnblogs.com/phile/p/4473191.html
Copyright © 2020-2023  润新知