Advertisement
MadCortez

Untitled

Sep 22nd, 2020
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.08 KB | None | 0 0
  1. const
  2. sz=100000; //sz=maxN
  3.  
  4. var // Дерево суммы
  5. b,ans:int64; // массив длины n
  6. i,n,t,q,st,fn,l_q,r_q,size:longint; // q запросов
  7. l,r,ch1,ch2:array [1..4*sz] of longint; // запрос вида "1 l_q r_q" - сумма на отрезке [l_q,r_q]
  8. push,tree:array [1..4*sz] of longint; // запрос вида "2 l_q r_q b" - прибавить на отрезке [l_q,r_q] число
  9. // b ко всем элементам
  10. function min(a,b:longint):longint;
  11. begin
  12. if a<b then
  13. min:=a
  14. else
  15. min:=b;
  16. end;
  17.  
  18. function max(a,b:longint):longint;
  19. begin
  20. if a>b then
  21. max:=a
  22. else
  23. max:=b;
  24. end;
  25.  
  26. procedure build(i:longint); // рекурсия заполения дерева
  27. begin
  28. if l[i]=r[i] then // если лист - выходим
  29. exit;
  30. build(ch1[i]); // запускае рекурсию
  31. build(ch2[i]); // от детей
  32. tree[i]:=tree[ch1[i]]+tree[ch2[i]]; // значение ячейки - сумма ячеек-детей
  33. end;
  34.  
  35. procedure find(i,l_q,r_q:longint); // рекурсия подсчета ответа
  36. begin
  37. if push[i]>0 then // провеляем наличие обещаний
  38. begin // (push[i] - обещание на i-ую ячейку)
  39. tree[i]:=tree[i]+push[i]*(r[i]-l[i]+1); // выполняем оббещание
  40. if l[i]<>r[i] then
  41. begin
  42. push[ch1[i]]:=push[ch1[i]]+push[i]; // передаем обещания
  43. push[ch2[i]]:=push[ch2[i]]+push[i]; // детям
  44. end;
  45. push[i]:=0; // выполнили обещания - обнуляем
  46. end;
  47. if (l[i]=l_q) and (r[i]=r_q) then // если запрос соответствует отрезку ячейки
  48. begin
  49. ans:=ans+tree[i]; // добавляем сумму ячейки к ответу
  50. exit; // выходим
  51. end;
  52. if l_q<=r[ch1[i]] then // проверяем, нужно ли спрашивать у левого сына
  53. find(ch1[i],l_q,min(r_q,r[ch1[i]])); // спрашиваем у левого сына в нужных границах
  54. if r_q>=l[ch2[i]] then // проверяем, нужно ли спрашивать у правого сына
  55. find(ch2[i],max(l_q,l[ch2[i]]),r_q); // спрашиваем у правого сына в нужных границах
  56. end;
  57.  
  58. procedure modify(i,l_q,r_q,b:longint); // рекурсия изменения дерева
  59. begin
  60. tree[i]:=tree[i]+b*(r_q-l_q+1); // увеличиваем на длину отрезка отрезок
  61. if (l[i]=l_q) and (r[i]=r_q) then // если запрос соответствует отрезку ячейки
  62. begin
  63. if l[i]<>r[i] then // если не лист
  64. begin
  65. push[ch1[i]]:=push[ch1[i]]+b; // даем обещания
  66. push[ch2[i]]:=push[ch2[i]]+b; // детям
  67. end;
  68. exit;
  69. end;
  70. if l_q<=r[ch1[i]] then // проверяем, нужно ли изменять левого сына
  71. modify(ch1[i],l_q,min(r_q,r[ch1[i]]),b); // изменяем левого сына в нужных границах
  72. if r_q>=l[ch2[i]] then // проверяем, нужно ли изменять правого сына
  73. modify(ch2[i],max(l_q,l[ch2[i]]),r_q,b); // изменяем правого сына в нужных границах
  74. end;
  75.  
  76.  
  77. begin
  78. readln(n,q);
  79. size:=1;
  80. while n>size do // вычисляем size - количество эллементов на последнем
  81. size:=size*2; // уровне дерева (добиаваем до степени двойки)
  82. l[1]:=1; // границы первой ячейки
  83. r[1]:=size;
  84. fn:=1;
  85. st:=0;
  86. while true do // запускаем цикл (можно бесконечный)
  87. begin
  88. inc(st);
  89. if l[st]=r[st] then // проверяем: если это лист - ввыходим из цикла
  90. break;
  91. inc(fn); // создаем левого сына
  92. ch1[st]:=fn;
  93. l[fn]:=l[st];
  94. r[fn]:=(l[st]+r[st]) div 2;
  95. inc(fn); // создаем правого сына
  96. ch2[st]:=fn;
  97. l[fn]:=r[fn-1]+1;
  98. r[fn]:=r[st];
  99. end;
  100. for i:=1 to n do
  101. begin
  102. read(tree[st]); // зачитываем массив
  103. inc(st); // на последний уровень дерева
  104. end;
  105. build(1); // запускаем рекурсию заполнения дерева
  106. for i:=1 to q do // начинаем обрабатывать запросы
  107. begin
  108. read(t,l_q,r_q);
  109. if t=1 then // запрос суммы
  110. begin
  111. ans:=0; // обнуляем ответ
  112. find(1,l_q,r_q); // запускаем рекурсию подсчета ответа
  113. writeln(ans);
  114. continue;
  115. end;
  116. if t=2 then // запрос изменения
  117. begin
  118. read(b);
  119. modify(1,l_q,r_q,b); // запускаем рекурсию изменения дерева
  120. continue;
  121. end;
  122. end;
  123. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement