比赛 20120711 评测结果 AAAAAAAAAAAA
题目名称 平衡奶牛 最终得分 100
用户昵称 IMSL77 运行时间 0.705 s
代码语言 Pascal 内存使用 28.70 MiB
提交时间 2012-07-11 11:57:52
显示代码纯文本
program balline;
type
  integer=longint;
const
  maxn=110000;
  maxk=31;
var
  n,k:integer;
  root,tot:integer;
  a:array[1..maxn] of integer;
  sum:array[0..maxn,1..maxk] of integer;
  cow:array[0..maxn,1..maxk] of integer;
  left,right:array[1..maxn] of integer;
  key:array[1..maxn] of integer;
  pro:array[0..maxn] of real;

  procedure Fopen;
  begin
    assign(input,'balline.in'); reset(input);
    assign(output,'balline.out'); rewrite(output);
  end;

  procedure Fclose;
  begin
    close(input); close(output);
  end;

  procedure Init;
  var
    i:integer;
  begin
    readln(n,k);
    for i:=1 to n do read(a[i]);
  end;

  procedure ClearTreap;
  begin
    fillchar(left,sizeof(left),0);
    fillchar(right,sizeof(right),0);
    root:=0; tot:=0;
    pro[0]:=2;
  end;

  function equal(x,y:integer):boolean;
  var
    i:integer;
  begin
    for i:=1 to k do if cow[x,i]<>cow[y,i] then exit(false);
    exit(true);
  end;

  function less(x,y:integer):boolean;
  var
    i:integer;
  begin
    for i:=1 to k do
    begin
      if cow[x,i]<cow[y,i] then exit(true);
      if cow[x,i]>cow[y,i] then exit(false);
    end;
    exit(false);
  end;

  function Search(root,x:integer):integer;
  begin
    if root=0 then exit(-1);
    if equal(x,key[root]) then exit(key[root]);
    if less(x,key[root]) then exit(Search(left[root],x))
                         else exit(Search(right[root],x));
  end;

  procedure Left_Rotate(var k:integer);
  var
    t:integer;
  begin
    t:=right[k]; right[k]:=left[t];
    left[t]:=k; k:=t;
  end;

  procedure Right_Rotate(var k:integer);
  var
    t:integer;
  begin
    t:=left[k]; left[k]:=right[t];
    right[t]:=k; k:=t;
  end;

  procedure Insert(var root:integer; x:integer);
  begin
    if root=0 then
    begin
      inc(tot); root:=tot;
      key[root]:=x; pro[root]:=random;
      exit;
    end;
    if less(x,key[root]) then
    begin
      Insert(left[root],x);
      if pro[left[root]]<pro[root] then Right_Rotate(root);
    end else
    begin
      Insert(right[root],x);
      if pro[right[root]]<pro[root] then Left_Rotate(root);
    end;
  end;

  procedure Solve;
  var
    i,j:integer;
    ans:integer;
  begin
    fillchar(sum,sizeof(sum),0);
    for i:=1 to n do
      for j:=1 to k do
      begin
        sum[i,j]:=sum[i-1,j];
        if a[i] and (1 shl (j-1))>0 then inc(sum[i,j]);
      end;
    fillchar(cow,sizeof(cow),0);
    for i:=0 to n do
      for j:=1 to k-1 do
        cow[i,j]:=sum[i,j+1]-sum[i,j];
    dec(k);
    ClearTreap;
    ans:=0;
    for i:=0 to n do
    begin
      j:=Search(root,i);
      if j>-1 then begin if i-j>ans then ans:=i-j; end
      else Insert(root,i);
    end;
    writeln(ans);
  end;

begin
  Fopen;
  Init;
  Solve;
  Fclose;
end.