• BZOJ1858: [Scoi2010]序列操作


    1858: [Scoi2010]序列操作

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1068  Solved: 545
    [Submit][Status]

    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<n)表示对于区间[a, b]执行标号为op的操作="" <="" div="">

    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

    Day2

    这题的区间合并实在太恶心了,写完我都快吐了。。。那天过来再调吧。。。

    代码:

      1 {$inline on}
      2 {$M 1000000000,0,maxlongint}
      3 const maxn=100000+1000;
      4 var s,sum1,sum0,v,lx0,rx0,lx1,rx1,mx0,mx1,fa,id,a:array[0..maxn] of longint;
      5     rev,tag:array[0..maxn] of boolean;
      6     c:array[0..maxn,0..1] of longint;
      7     i,n,m,x,y,z,rt,ch,ll,rr:longint;
      8     procedure swap(var x,y:longint);inline;
      9      var t:longint;
     10      begin
     11       t:=x;x:=y;y:=t;
     12      end;
     13     function max(x,y:longint):longint;inline;
     14      begin
     15       if x>y then exit(x) else exit(y);
     16      end;
     17 procedure pushup(x:longint);
     18  var l,r:longint;
     19  begin
     20    l:=c[x,0];r:=c[x,1];
     21    s[x]:=s[l]+s[r]+1;
     22    sum1[x]:=sum1[l]+sum1[r]+ord(v[x]=1);
     23    sum0[x]:=sum0[l]+sum0[r]+ord(v[x]=0);
     24    if lx0[l]=s[l] then
     25      begin
     26      if v[x]=0 then lx0[x]:=s[l]+1+lx0[r]
     27      else lx0[x]:=s[l];
     28      end
     29    else lx0[x]:=lx0[l];
     30    if rx0[r]=s[r] then
     31      begin
     32      if v[x]=0 then rx0[x]:=s[r]+1+rx0[l]
     33      else rx0[x]:=s[r];
     34      end;
     35    if lx1[l]=s[l] then
     36      begin
     37      if v[x]=1 then lx1[x]:=s[l]+1+lx1[r]
     38      else lx1[x]:=s[l];
     39      end
     40    else lx1[x]:=lx1[l];
     41    if rx1[r]=s[r] then
     42      begin
     43      if v[x]=1 then rx1[x]:=s[r]+1+rx1[l]
     44      else rx1[x]:=s[r];
     45      end;
     46    mx0[x]:=max(mx0[l],mx0[r]);
     47    if v[x]=0 then mx0[x]:=max(mx0[x],rx0[l]+lx0[r]+1);
     48    mx1[x]:=max(mx1[l],mx1[r]);
     49    if v[x]=1 then mx1[x]:=max(mx1[x],rx1[l]+lx1[r]+1);
     50  end;
     51 procedure rotate(x:longint;var k:longint);
     52  var y,z,l,r:longint;
     53  begin
     54    y:=fa[x];z:=fa[y];
     55    l:=ord(c[y,1]=x);r:=l xor 1;
     56    if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x;
     57    fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y;
     58    c[y,l]:=c[x,r];c[x,r]:=y;
     59    pushup(y);pushup(x);
     60  end;
     61 procedure splay(x:longint;var k:longint);
     62  var y,z:longint;
     63  begin
     64    while x<>k do
     65     begin
     66       y:=fa[x];z:=fa[y];
     67       if y<>k then
     68        if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k)
     69        else rotate(y,k);
     70       rotate(x,k);
     71     end;
     72  end;
     73 
     74 
     75 procedure build(l,r,f:longint);
     76  var mid,x,y:longint;
     77    begin
     78     if l>r then exit;
     79     mid:=(l+r)>>1;
     80     x:=id[mid];y:=id[f];
     81     c[y,ord(mid>f)]:=x;fa[x]:=y;
     82     v[x]:=a[mid];
     83     if l=r then
     84       begin
     85       s[x]:=1;sum0[x]:=ord(v[x]=0);sum1[x]:=ord(v[x]=1);
     86       lx0:=sum0;rx0:=sum0;mx0:=sum0;
     87       lx1:=sum1;rx1:=sum1;mx1:=sum1;
     88       exit;
     89       end;
     90     build(l,mid-1,mid);build(mid+1,r,mid);
     91     pushup(x);
     92    end;
     93 procedure init;
     94  begin
     95    readln(n,m);
     96    a[1]:=-1;a[n+2]:=-1;
     97    for i:=2 to n+1 do read(a[i]);readln;
     98    for i:=1 to n+2 do id[i]:=i;
     99    build(1,n+2,0);rt:=(n+3)>>1;
    100  end;
    101 procedure same0(x:longint);
    102  begin
    103   tag[x]:=true;v[x]:=0;
    104   sum0[x]:=s[x];lx0[x]:=s[x];rx0[x]:=s[x];mx0[x]:=s[x];
    105   sum1[x]:=0;lx1[x]:=0;rx1[x]:=0;mx1[x]:=0;
    106  end;
    107 procedure same1(x:longint);
    108  begin
    109   tag[x]:=true;v[x]:=1;
    110   sum1[x]:=s[x];lx1[x]:=s[x];rx1[x]:=s[x];mx1[x]:=s[x];
    111   sum0[x]:=0;lx0[x]:=0;rx0[x]:=0;mx0[x]:=0;
    112  end;
    113 procedure rever(x:longint);
    114  begin
    115   if (x=0) or (tag[x]) then exit;
    116   rev[x]:=not(rev[x]);v[x]:=v[x] xor 1;
    117   swap(lx0[x],lx1[x]);
    118   swap(rx0[x],rx1[x]);
    119   swap(sum0[x],sum1[x]);
    120   swap(mx0[x],mx1[x]);
    121  end;
    122 procedure pushdown(x:longint);
    123  var l,r:longint;
    124  begin
    125   l:=c[x,0];r:=c[x,1];
    126   if tag[x] then
    127    begin
    128    tag[x]:=false;rev[x]:=false;
    129    if v[x]=0 then begin same0(l);same0(r);end
    130    else begin same1(l);same1(r);end;
    131    end;
    132   if rev[x] then
    133    begin
    134    rev[x]:=false;
    135    rever(l);rever(r);
    136    pushup(x);
    137    end;
    138  end;
    139 
    140 function find(x,rk:longint):longint;
    141  var l,r:longint;
    142  begin
    143    pushdown(x);l:=c[x,0];r:=c[x,1];
    144    if s[l]+1=rk then exit(x)
    145    else if s[l]>=rk then exit(find(l,rk))
    146    else exit(find(r,rk-s[l]-1));
    147  end;
    148 
    149 procedure split(l,r:longint;var x,y:longint);
    150  begin
    151    x:=find(rt,l);y:=find(rt,r);
    152    splay(x,rt);splay(y,c[x,1]);
    153  end;
    154 procedure main;
    155  begin
    156    for i:=1 to  m do
    157     begin
    158       readln(ch,ll,rr);inc(ch);inc(ll,1);inc(rr,3);
    159       split(ll,rr,x,y);
    160       case ch of
    161       1:same0(c[y,0]);
    162       2:same1(c[y,0]);
    163       3:rever(c[y,0]);
    164       4:writeln(sum1[c[y,0]]);
    165       5:writeln(mx1[c[y,0]]);
    166       end;
    167     end;
    168  end;
    169 begin
    170   assign(input,'input.txt');assign(output,'output.txt');
    171   reset(input);rewrite(output);
    172   init;
    173   main;
    174   close(input);close(output);
    175 end.
    176       
    View Code

     UPD:这是一份错的代码。。。

    正解戳这里额:http://www.cnblogs.com/zyfzyf/p/3940159.html

  • 相关阅读:
    高阶函数 练习
    斐波那契数列(Fibonacci sequence)递归函数
    顺序循环队列的基本操作(二)
    顺序循环队列基本操作(一)
    顺序栈的基本操作
    双链表的插入删除
    头插法实现链表逆置
    带头结点单链表的基本操作
    顺序表基本操作
    实现原数组列变成行,再将每一行首尾倒置
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3902669.html
Copyright © 2020-2023  润新知