ENG  RUSTimus Online Judge
Online Judge
Problems
Authors
Online contests
About Online Judge
Frequently asked questions
Site news
Webboard
Links
Problem set
Submit solution
Judge status
Guide
Register
Update your info
Authors ranklist
Current contest
Scheduled contests
Past contests
Rules
back to board

Discussion of Problem 1846. GCD 2010

Need some help
Posted by Combatcook 1 Nov 2016 21:21
Hi! I tried to solve this problem with interval tree and BST, but have TLE. It seems to me that it is due to the fact that there is endless loop or something like that in my program. Anyway, can someone help me to find the bug in my code:
type segment_tree = array[0..400000] of longint;   // дерево отрезков
     bintree = array[0..100000] of record    // бинарное дерево поиска
       key,left,right,par: longint;
     end;
var t: segment_tree;
    b: bintree;
    c: char;
    i,j,n,k,p,m,root: longint;
function nod(a,b: longint): longint; // бинарный алгоритм нахождения нод
var m,n,d: longint;
begin
 m:=a; n:=b; d:=1;
 while not((m=0) or (n=0)) do begin
  if (m mod 2=0) and (n mod 2=0) then begin
   d:=d shl 1; m:=m shr 1; n:=n shr 1;
  end else if (m mod 2=0) and (n mod 2=1) then begin
   m:=m shr 1;
  end else if (m mod 2=1) and (n mod 2=0) then begin
   n:=n shr 1;
  end else if (m mod 2=1) and (n mod 2=1) and (m>=n) then begin
   m:=m-n;
  end else if (m mod 2=1) and (n mod 2=1) and (m<=n) then begin
   n:=n-m;
  end;
 end;
 if m=0 then nod:=d*n else if n=0 then nod:=d*m;
end;
procedure upd(v,tl,tr,wo,neu: longint); // обновление дерева отрезков
var tm,p: longint;
begin
  p:=1;
  while tl<>tr do begin
   tm:=(tl+tr) div 2;
   if wo>tm then begin tl:=tm+1; p:=p shl 1+1; end
   else begin tr:=tm; p:=p shl 1; end;
  end;
  t[p]:=neu;
  while p>v do begin
   p:=p shr 1;
   t[p]:=nod(t[p*2],t[p*2+1]);
  end;
end;
function find(x,st: longint): longint; // поиск элемента в бинарном дереве
begin
  while b[st].key<>x do
  if x>b[st].key then st:=b[st].right
                 else st:=b[st].left;
  find:=st;
end;
procedure insert(x,st: longint; var root: longint); // вставка элемента
begin
  if root=0 then root:=x else begin
  if b[x].key>=b[st].key then begin
    if b[st].right=0 then begin
       b[st].right:=x;
       b[x].par:=st;
    end
    else insert(x,b[st].right,root);
  end
  else begin
    if b[st].left=0 then begin
       b[st].left:=x;
       b[x].par:=st;
    end
    else insert(x,b[st].left,root);
  end;
 end;
end;
procedure del(x: longint; var root: longint); // удаление элемента
var p: longint;
begin
 // если в дереве одна вершина, обнуляем корень
  if (b[x].left=0) and (b[x].right=0) and (b[x].par=0) then root:=0
  else
  // если удаляем лист, убираем ссылку на элемент у родителя
  if (b[x].left=0) and (b[x].right=0) and (b[x].par<>0) then begin
    if b[x].key>=b[b[x].par].key then b[b[x].par].right:=0
                                 else b[b[x].par].left:=0;
  end else
  // если есть только правый сын, "адресуем" сына и родителя элемента
  // друг на друга
  if (b[x].left=0) then begin
    b[b[x].right].par:=b[x].par;
    if b[x].key>=b[b[x].par].key then b[b[x].par].right:=b[x].right
                                 else b[b[x].par].left:=b[x].right;
   if b[b[x].right].par=0 then root:=b[x].right;
  end else
  // аналогично если есть только левый сын
  if (b[x].right=0) then begin
    b[b[x].left].par:=b[x].par;
    if b[x].key>=b[b[x].par].key then b[b[x].par].right:=b[x].left
                                 else b[b[x].par].left:=b[x].left;
    if b[b[x].left].par=0 then root:=b[x].left;
  end else
  // если оба сына есть
  if (b[x].right<>0) and (b[x].left<>0) then begin
  // идем в самый левый элемент правого сына - р
    p:=b[x].right;
    while b[p].left<>0 do p:=b[p].left;
  // если у р есть правый сын, "подвешиваем" его к родителю р
    if b[p].right<>0 then begin
      b[b[p].right].par:=b[p].par;
      b[b[p].par].left:=b[p].right;
    end;
  // все ссылки на удаляемый элемент присваиваем элементу р
    b[b[x].left].par:=p;
    b[b[x].right].par:=p;
    if b[x].key>=b[b[x].par].key then b[b[x].par].right:=p
                                 else b[b[x].par].left:=p;
    b[p].left:=b[x].left;
    b[p].right:=b[x].right;
    b[p].par:=b[x].par;
    if b[b[p].par].left=p then b[b[p].par].left:=0;
    if b[p].left=p then b[p].left:=0;
    if b[p].right=p then b[p].right:=0;
   if b[p].par=0 then root:=p;
  end;
end;
begin
 readln(n); p:=0; root:=0;
 for i:= 1 to n do begin
  readln(c,k);
  if c='+' then begin
    inc(p);
    b[p].key:=k;
    insert(p,root,root);
    upd(1,0,n-1,p,k);
  end
  else begin
    m:=find(k,root);
    del(m,root);
    b[m].key:=0;
    upd(1,0,n-1,m,0);
  end;
  if t[1]=0 then writeln(1) else writeln(t[1]);
 end;
end.