Advertisement
reiziger

Segment tree

Jan 16th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.34 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <cmath>
  4. #include <vector>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. typedef long long ll;
  10. typedef long double ld;
  11. typedef pair <ll, ll> pl;
  12. typedef pair <ld, ld> pd;
  13.  
  14. const ll N = 1e6 + 100;
  15. const ll P = 1e9 + 7;
  16. const ll M = 1e4 + 10;
  17. const ld pi = acos(-1);
  18. const ll INF = 1e18;
  19.  
  20. #define x first
  21. #define y second
  22. #define pb push_back
  23.  
  24. vector <ll> v;
  25.  
  26. struct node
  27. {
  28. ll left, right, max, sum = 0, add = 0;
  29. node *child_left, *child_right;
  30. };
  31.  
  32. node* build(ll left, ll right, vector <ll> &v) //строим дерево отрезков
  33. {
  34. if (left > right)
  35. return NULL;
  36.  
  37. node *res = new node;
  38. res->left = left,
  39. res->right = right;
  40.  
  41. if (left == right)
  42. {
  43. res->child_left = NULL;
  44. res->child_right = NULL;
  45. res->sum = v[left];
  46. res->max = v[left];
  47. }
  48. else
  49. {
  50. ll mid = (left + right) / 2;
  51. res->child_left = build(left, mid, v);
  52. res->child_right = build(mid + 1, right, v);
  53. res->sum = res->child_left->sum + res->child_right->sum;
  54. res->max = max(res->child_left->max, res->child_right->max);
  55. }
  56. return res;
  57. }
  58.  
  59. ll query_sum(node *root, ll left, ll right) // ищем сумму на отрезке [L;R]
  60. {
  61. if (right < root->left || left > root->right)
  62. return 0;
  63.  
  64. if (left <= root->left && right >= root->right)
  65. return root->sum + root->add;
  66.  
  67. ll ans1 = query_sum(root->child_left, left, right),
  68. ans2 = query_sum(root->child_right, left, right);
  69.  
  70. return root->add + ans1 + ans2;
  71. }
  72.  
  73. ll query_max(node *root, ll left, ll right) // ищем максимум на отрезке [L;R]
  74. {
  75. if (right < root->left || left > root->right)
  76. return -INF;
  77.  
  78. if (left <= root->left && right >= root->right)
  79. return root->max + root->add;
  80.  
  81. ll ans1 = query_max(root->child_left, left, right);
  82. ll ans2 = query_max(root->child_right, left, right);
  83.  
  84. return root->add + max(ans1, ans2);
  85. }
  86.  
  87. void update(node *root, ll ind, ll x) //помещаем в элемент под индексом ind значение x
  88. {
  89. if (ind < root->left || ind > root->right)
  90. return;
  91.  
  92. if (root->left == root->right)
  93. {
  94. root->sum = x;
  95. root->max = x;
  96. return;
  97. }
  98.  
  99. update(root->child_left, ind, x);
  100. update(root->child_right, ind, x);
  101. root->sum = root->child_left->sum + root->child_right->sum;
  102. root->max = max(root->child_left->max, root->child_right->max);
  103. }
  104.  
  105. void update_on_segment(node *root, ll left, ll right, ll delta) //прибавляем какое-то delta к элементам [L;R]
  106. {
  107. if (right < root->left || left > root->right)
  108. return;
  109.  
  110. if (left <= root->left && right >= root->right)
  111. root->add += delta;
  112. else
  113. {
  114. update_on_segment(root->child_left, left, right, delta);
  115. update_on_segment(root->child_right, left, right, delta);
  116.  
  117. root->sum = root->child_left->sum + root->child_left->add +
  118. root->child_right->sum + root->child_right->add;
  119.  
  120. root->max = max(root->child_left->max + root->child_left->add,
  121. root->child_right->max + root->child_right->add);
  122. }
  123.  
  124. }
  125. int main()
  126. {
  127. ll n;
  128. cin >> n;
  129.  
  130. v.resize(n);
  131.  
  132. for (ll i = 0; i < n; i++)
  133. cin >> v[i];
  134.  
  135. node *root = build(0, n - 1, v);
  136.  
  137. ll m;
  138. cin >> m;
  139.  
  140. for (ll i = 0; i < m; i++)
  141. {
  142. ll left, right;
  143. cin >> left >> right;
  144. left--, right--;
  145.  
  146. cout << query_max(root, left, right) << " ";
  147. }
  148. return 0;
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement