agul

Untitled

Jul 4th, 2011
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 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.
Add Comment
Please, Sign In to add comment