ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила
вернуться в форум

Обсуждение задачи 1019. Перекрашивание прямой

Why? Memory Limit exceeded!(On test #11) How can that be possible?
Послано JIM 18 июл 2004 19:21
I've met this problem for several times on URAL, and still unsolved yet. Please help me.
I think that I've only used 5000*(8+1){for a} + 5000*2*4{for x} + 5000*2*(4+1+6+1){for the whole linetree}, that's 205Kb, much less that 1000Kb.  But URAL says 'Memory Limit Exceeded!'(On test #11). Can you help me?

Here is my program:
const
  maxn=5010;
type
  a_type=record
           x1,x2:longint;
           c:0..1;
         end;
  tree=^node;
  node=record
         ltr,rtr:tree;
         c:0..1;
         max,l_max,r_max:longint;
         leaf:boolean;
       end;
var
  a:array[1..maxn] of a_type;
  x:array[1..maxn*2+2] of longint;
  n,i:integer;
  root:tree;

procedure readdata;
  var i:integer;
      ch:char;
  begin
    assign(input,'1019.in'); reset(input);
    readln(n);
    x[1]:=0; x[2]:=1000000000;
    for i:=1 to n do begin
      read(a[i].x1,a[i].x2);
      x[i*2+1]:=a[i].x1;
      x[i*2+2]:=a[i].x2;
      repeat read(ch) until ch in ['b','w'];
      if ch='b' then a[i].c:=1
                else a[i].c:=0;
      readln;
    end;
    close(input);
  end;

procedure qsort(p,r:integer);
  var x0,tp:longint;
      i,j:integer;
  begin
    if p>=r then exit;
    x0:=x[p+random(r-p+1)];
    i:=p-1; j:=r+1;
    while true do begin
      repeat inc(i); until x[i]>=x0;
      repeat dec(j); until x[j]<=x0;
      if i<j then
        begin tp:=x[i]; x[i]:=x[j]; x[j]:=tp; end
      else break;
    end;
    qsort(p,j);
    qsort(j+1,r);
  end;

function bi_search(x0:longint):integer;
  var p,r,q:integer;
  begin
    p:=1; r:=n*2+2;
    while p<>r do begin
      q:=(p+r) div 2;
      if x0<=x[q] then r:=q
                  else p:=q+1;
    end;
    bi_search:=p;
  end;

procedure build(t:tree; p,r:integer);
  begin
    if p+1=r then begin
      t^.ltr:=nil; t^.rtr:=nil;
    end else begin
      new(t^.ltr);
      build(t^.ltr,p,(r+p) div 2);
      new(t^.rtr);
      build(t^.rtr,(r+p) div 2,r);
    end;
  end;

procedure init;
  var i:integer;
  begin
    for i:=1 to n do begin
      a[i].x1:=bi_search(a[i].x1);
      a[i].x2:=bi_search(a[i].x2);
    end;
    new(root);
    build(root,1,n*2+2);
    root^.c:=0; root^.leaf:=true;
    root^.max:=1000000000; root^.l_max:=root^.max; root^.r_max:=root^.max;
  end;

function larger(x,y,z:longint):longint;
  begin
    if (x>y) then
      if (x>z) then larger:=x
      else larger:=z
    else
      if (y>z) then larger:=y
      else larger:=z;
  end;

procedure insert(t:tree; B,E,p,r:integer; c:byte);
  begin
    if t^.leaf and (t^.c=c) then exit;
    if (p<=B) and (r>=E) then begin
      t^.c:=c;
      t^.leaf:=true;
      if c=0 then t^.max:=x[E]-x[B]
             else t^.max:=0;
      t^.l_max:=t^.max;
      t^.r_max:=t^.max;
    end else begin
      if t^.leaf then begin
        t^.leaf:=false;
        t^.ltr^.c:=t^.c;
        t^.ltr^.leaf:=true;
        t^.rtr^.c:=t^.c;
        t^.rtr^.leaf:=true;
        if t^.c=0 then begin
          t^.ltr^.max:=x[(B+E) div 2]-x[B];
          t^.rtr^.max:=x[E]-x[(B+E) div 2];
        end else begin
          t^.ltr^.max:=0;
          t^.rtr^.max:=0;
        end;
        t^.ltr^.l_max:=t^.ltr^.max;
        t^.ltr^.r_max:=t^.ltr^.max;
        t^.rtr^.l_max:=t^.rtr^.max;
        t^.rtr^.r_max:=t^.rtr^.max;
      end;
      if p<(B+E) div 2 then
        insert(t^.ltr,B,(B+E) div 2,p,r,c);
      if r>(B+E) div 2 then
        insert(t^.rtr,(B+E) div 2,E,p,r,c);
      t^.max:=larger(t^.ltr^.max , t^.rtr^.max , t^.ltr^.r_max+t^.rtr^.l_max);
      t^.l_max:=t^.ltr^.l_max;
      if t^.l_max=x[(B+E) div 2]-x[B] then
        inc(t^.l_max,t^.rtr^.l_max);
      t^.r_max:=t^.rtr^.r_max;
      if t^.r_max=x[E]-x[(B+E) div 2] then
        inc(t^.r_max,t^.ltr^.r_max);
    end;
  end;

procedure print(t:tree; B,E:integer; x0:longint);
  begin
    if x[E]-x[B]=x0 then
      writeln(x[B],' ',x[E])
    else if t^.ltr^.max=x0 then
      print(t^.ltr,B,(B+E) div 2,x0)
    else if t^.ltr^.r_max+t^.rtr^.l_max=x0 then
      writeln(x[(B+E) div 2]-t^.ltr^.r_max,' ',x[(B+E) div 2]+t^.rtr^.l_max)
    else
      print(t^.rtr,(B+E) div 2,E,x0);
  end;

begin
  readdata;
  qsort(1,n*2+2);
  init;
  for i:=1 to n do
    if a[i].x1<a[i].x2 then
      insert(root,1,n*2+2,a[i].x1,a[i].x2,a[i].c);
  print(root,1,n*2+2,root^.max);
end.