Advertisement
agul

Problem 753

Jul 4th, 2011
602
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 3.46 KB | None | 0 0
  1. uses
  2.     SysUtils, Math;
  3.  
  4. const
  5.     bad:int64=-round(1e12); // -INFINITY
  6.  
  7. var    
  8.     i,n,q,qq,tt,x,y,tp,k,kk,cc,l,r:longint;
  9.     a,b:array[0..400010] of int64;
  10.      
  11. function maxI(x,y:longint):longint; // получает индексы элементов, возвращает индекс максимального элемента
  12. begin
  13. if b[x]>b[y] then result:=x else result:=y;
  14. end;
  15.  
  16. function build(n:longint):longint; // производит предподсчет
  17.  
  18. var                                
  19.     k,i,j:longint;
  20.    
  21. begin
  22. k:=1;
  23. while k<=n do k:=k shl 1;
  24. kk:=k;
  25. k:=k shl 1;
  26. b[0]:=bad;
  27. for i:=n+1 to kk do
  28.     b[i]:=bad;
  29. j:=1;
  30. for i:=kk to k do begin
  31.     a[i]:=j;
  32.     inc(j);
  33. end;
  34. for i:=kk-1 downto 1 do
  35.     a[i]:=maxI(a[i*2],a[i*2+1]);
  36. result:=k;
  37. end;
  38.  
  39. function rmq(l,r:longint):longint; // получает индексы элементов, возвращает индекс максимального на отрезке
  40. var
  41.     kk:longint;
  42. begin
  43. kk:=k shr 1;
  44. inc(l,kk-1);
  45. inc(r,kk-1);
  46. result:=maxI(a[l],a[r]);
  47. while r-l>1 do begin
  48.     if l mod 2=0 then result:=maxI(result,a[l+1]);  // если левый сын
  49.     if r mod 2=1 then result:=maxI(result,a[r-1]);  // если правый сын
  50.     l:=l div 2;
  51.     r:=r div 2;
  52. end;
  53. end;
  54.  
  55. procedure update(v:longint); // пересчитывает дерево после изменения элемента
  56. begin
  57. v:=v div 2;
  58. while v>=1 do begin
  59.     a[v]:=maxI(a[2*v],a[2*v+1]);
  60.     v:=v div 2;
  61. end;
  62. end;
  63.  
  64. begin  // B - массив с числами; А - дерево, в котором мы храним индексы
  65. reset(input,'input.txt');
  66. rewrite(output,'output.txt');
  67. fillchar(a,sizeof(a),0);    // обнуляем массивы
  68. fillchar(b,sizeof(b),0);
  69. read(n,q);
  70. k:=build(n);               // строим первичное дерево (особого смысла нет, только получаем максимальный размер)
  71. cc:=0;                     // счетчик максимального количества групп
  72. for qq:=1 to q do begin
  73.     read(tp);
  74.     if tp=1 then begin
  75.         read(x,y);
  76.         tt:=rmq(x,y);           // находим максимум на отрезке
  77.         if b[tt]=0 then begin   // если он равен 0, то ни один элемент не входит ни в одну группу
  78.             inc(cc);              // увеличиваем счетчик
  79.             for i:=x to y do begin  // изменяем все элементы отрезка
  80.                 b[i]:=cc;
  81.                 update(i);
  82.             end;
  83.             writeln(1);             // пишем, что ОК
  84.         end else writeln(0);      // иначе пишем, что нельзя объединить
  85.     end else
  86.     if tp=2 then begin
  87.         read(x);
  88.         tt:=b[x];                
  89.         b[x]:=0;
  90.         if tt>0 then begin        // если элемент принадлежит какой-нибудь группе
  91.             l:=x-1;
  92.             r:=x+1;
  93.             while (b[r]=tt) and (r<=n) do begin // находим правую границу, попутно обнуляя элементы
  94.                 b[r]:=0;
  95.                 update(r);
  96.                 inc(r);
  97.             end;
  98.             while (b[l]=tt) and (l>0) do begin  // находим левую границу, попутно обнуляя элементы
  99.                 b[l]:=0;
  100.                 update(l);
  101.                 dec(l);
  102.             end;
  103.             writeln(l+1,' ',r-1);               // выводим границы
  104.         end else writeln('0 0');              // если элемент не относится ни к одной из групп - выводим дво нуля
  105.     end;
  106. end;
  107.  
  108. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement