Advertisement
Guest User

Untitled

a guest
Jul 16th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.65 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cinttypes>
  3. #include <cstdlib>
  4. #include <limits>
  5. #include <array>
  6.  
  7. typedef int64_t num_items;
  8.  
  9. namespace treap {
  10. template <class item_key, class item_value> struct treap;
  11.  
  12. template <class item_key, class item_value> struct node {
  13. item_key key;
  14. item_value value;
  15. item_key min;
  16. item_key max;
  17. item_value sum;
  18. num_items priority;
  19. num_items size;
  20. treap<item_key, item_value> left;
  21. treap<item_key, item_value> right;
  22. };
  23.  
  24. template <class item_key, class item_value> struct treap_pair {
  25. treap<item_key, item_value> left;
  26. treap<item_key, item_value> right;
  27. treap_pair() : left(nullptr), right(nullptr) {};
  28. };
  29.  
  30. template <class item_key, class item_value> treap<item_key, item_value> newTreapNode(item_key key, item_value value);
  31.  
  32. template <class item_key, class item_value> struct treap {
  33. node<item_key, item_value> *root;
  34. treap() { root = nullptr; }
  35. treap(node<item_key, item_value> *ptr) { root = ptr; }
  36.  
  37. treap(num_items numItems, item_key *keyArr, item_value *valueArr = nullptr) {
  38. //Return an empty treap if there are no items:
  39. if (numItems == 0) {
  40. root = nullptr;
  41. return;
  42. }
  43. //Return a treap with one item if there is an item:
  44. if (numItems == 1) {
  45. root = nullptr;
  46. addElementByKey(*keyArr, (valueArr == nullptr) ? 0 : *valueArr, false);
  47. return;
  48. }
  49.  
  50. //Find where the median is located:
  51. num_items medianPos = numItems/2;
  52. //Build the left and right sides accordingly:
  53. treap<item_key, item_value> leftSide(medianPos, keyArr, valueArr);
  54. treap<item_key, item_value> rightSide(numItems-medianPos, keyArr+medianPos, (valueArr == nullptr) ? nullptr : valueArr+medianPos);
  55. //Merge the two treaps together:
  56. root = mergeTreaps(leftSide, rightSide).root;
  57. }
  58.  
  59. num_items getSize() { return (root == nullptr) ? 0 : root->size; }
  60. item_key getMin() { return (root == nullptr) ? std::numeric_limits<item_key>::max() : root->min; }
  61. item_key getMax() { return (root == nullptr) ? std::numeric_limits<item_key>::min() : root->max; }
  62. item_value getSum() { return (root == nullptr) ? 0 : root->sum; }
  63. void updateProperties() {
  64. if (root != nullptr) {
  65. root->size = 1+root->left.getSize()+root->right.getSize();
  66. root->sum = root->value+root->left.getSum()+root->right.getSum();
  67. }
  68. }
  69.  
  70. static treap<item_key, item_value> mergeTreaps(treap<item_key, item_value> left, treap<item_key, item_value> right) {
  71. if (left.root == nullptr) return right;
  72. if (right.root == nullptr) return left;
  73. if (left.root->priority > right.root->priority) {
  74. left.root->right = mergeTreaps(left.root->right, right);
  75. left.updateProperties();
  76. return left;
  77. } else {
  78. right.root->left = mergeTreaps(left, right.root->left);
  79. right.updateProperties();
  80. return right;
  81. }
  82. }
  83.  
  84. //Split treap into a left-side with all elements less than or equal to key and a right-side with the rest of the elements.
  85. //Note that if exclusive is true, then left-side will have all elements less than key and right-side will have all elements greater than or equal to key.
  86. treap_pair<item_key, item_value> splitByKey(item_key key, bool exclusive) {
  87. treap_pair<item_key, item_value> answer;
  88. if (root == nullptr) return answer;
  89.  
  90. //If the key is less than the key of the root, then all items less than or equal to key are on the left-hand side.
  91. if (exclusive ? (key <= root->key) : (key < root->key)) {
  92. answer = root->left.splitByKey(key, exclusive);
  93. //Since answer.left is the tree rooted at key, make answer.right, which has all elements greater than key but less than the key of the root, the new left node of the treap:
  94. root->left = answer.right;
  95. //After making this modification, this becomes the right-side, which has all elements greater than key:
  96. answer.right = *this;
  97. }
  98. //If the key is greater than or equal to the key of the root, then we know that the left-side and the root is composed of all elements less than or equal to key, so we need to search the right-hand side for any other elements which are less than or equal to key.
  99. else {
  100. answer = root->right.splitByKey(key, exclusive);
  101. //Now, we need to combine this treap and its left-side with all of the elements in the right-side which are also less than or equal to key.
  102. //These elements are now in answer.left, so make answer.left the new right-side of treap:
  103. root->right = answer.left;
  104. //After making this modification, this becomes the left-side, which has all elements less than or equal to key:
  105. answer.left = *this;
  106. }
  107. updateProperties();
  108. return answer;
  109. }
  110.  
  111. item_value getKeyRangeSum(item_key startKey, item_key endKey) {
  112. //Split the treap up into a left-side which has all elements up to endKey:
  113. treap_pair<item_key, item_value> parts = splitByKey(endKey, false);
  114. //Split that treap up into a left-side which has all elements up to startKey-1:
  115. treap_pair<item_key, item_value> parts2 = parts.left.splitByKey(startKey, true);
  116. //Get the sum of the elements greater than startKey, less than or equal to endKey:
  117. item_value result = parts2.right.getSum();
  118. //Merge the treaps back together:
  119. root = mergeTreaps(mergeTreaps(parts2.left, parts2.right), parts.right).root;
  120. return result;
  121. }
  122.  
  123. bool addElementByKey(item_key newKey, item_value newValue, bool exclusive) {
  124. //Split treap up into a left-side with all elements less than newKey:
  125. treap_pair<item_key, item_value> parts = splitByKey(newKey, false);
  126. //Make sure newKey is not already in the tree:
  127. if (exclusive) {
  128. treap_pair<item_key, item_value> parts2 = parts.left.splitByKey(newKey, true);
  129. if (parts2.right.root != nullptr) {
  130. root = mergeTreaps(mergeTreaps(parts2.left, parts2.right), parts.right).root;
  131. return false;
  132. }
  133. parts.left = mergeTreaps(parts2.left, parts2.right);
  134. }
  135.  
  136. //Create a new node:
  137. treap<item_key, item_value> storeTreap = newTreapNode<item_key, item_value>(newKey, newValue);
  138. //Put the new node to the right of the left-side, and then merge the new left-side with the right-side:
  139. root = mergeTreaps(mergeTreaps(parts.left, storeTreap), parts.right).root;
  140.  
  141. return true;
  142. }
  143.  
  144. bool removeElementByKey(item_key oldKey) {
  145. //Split treap up into a left-side which has all elements up to oldKey:
  146. treap_pair<item_key, item_value> parts = splitByKey(oldKey, false);
  147. //Now, split the left-side up into a left-side which has all elements before oldKey and a right-side which has all elements equal to oldKey:
  148. treap_pair<item_key, item_value> parts2 = parts.left.splitByKey(oldKey, true);
  149. //Record whether there were actually any elements with oldKey:
  150. bool actuallyRemoved = parts2.right.root != nullptr;
  151. //Merge treaps back together without the elements equal to oldKey:
  152. root = mergeTreaps(parts2.left, parts.right).root;
  153.  
  154. return actuallyRemoved;
  155. }
  156.  
  157. //Split treap into a left-side with the first pos elements and a right-side with the rest of the elements.
  158. //The left-side will be rooted with the (pos-1)th item (0-based indexing), if it exists.
  159. treap_pair<item_key, item_value> splitByPos(num_items pos) {
  160. treap_pair<item_key, item_value> answer;
  161. if (this->root == nullptr) return answer;
  162. if (pos > getSize()) {
  163. answer.left = *this;
  164. return answer;
  165. }
  166.  
  167. num_items leftSize = root->left.getSize();
  168. //If the left-side has pos elements or more, then the (pos-1)th element is on the left-side:
  169. if (pos <= leftSize) {
  170. answer = root->left.splitByPos(pos);
  171. //Since answer.left is the tree rooted at (pos-1)th element, make answer.right, the elements between the (pos-1)th element and the root, the new left node of the treap:
  172. root->left = answer.right;
  173. //After making this modification, treap1 becomes the right-side, which has all elements after the (pos-1)th one:
  174. answer.right = *this;
  175. }
  176. //Otherwise, we need to split the right-side up to look for the (pos-1)th element:
  177. else {
  178. //Notice that we subtract pos by the number of elements in the root and left-side:
  179. answer = root->right.splitByPos(pos-leftSize-1);
  180. //Now, in order to get all of the first pos elements, we need to combine treap1 and its left-side with all of the elements in the right-side.
  181. //These elements are now in answer.left, so make answer.left the new right-side of treap:
  182. root->right = answer.left;
  183. //After making this modification, treap1 becomes the left-side, which has all of the first pos elements:
  184. answer.left = *this;
  185. }
  186. updateProperties();
  187. return answer;
  188. }
  189.  
  190. item_value getIntervalSum(num_items startPos, num_items endPos) {
  191. //Split the treap up into a left-side which has all elements up to endPos index:
  192. treap_pair<item_key, item_value> parts = splitByPos(endPos+1);
  193. //Split that treap up into a left-side which has all elements up to startPos-1 index:
  194. treap_pair<item_key, item_value> parts2 = parts.left.splitByPos(startPos);
  195. //Get the sum of the elements with index greater than startPos-1, less than or equal to endPos:
  196. item_value result = parts2.right.getSum();
  197. //Merge the treaps back together:
  198. root = mergeTreaps(mergeTreaps(parts2.left, parts2.right), parts.right).root;
  199. return result;
  200. }
  201.  
  202. void addElementByPos(num_items newPos, item_key newKey, item_value newValue) {
  203. //Split treap up into a left-side with first pos elements:
  204. treap_pair<item_key, item_value> parts = splitByPos(newPos);
  205. //Create the new node:
  206. treap<item_key, item_value> storeTreap = newTreapNode<item_key, item_value>(newKey, newValue);
  207. //Put the new node to the right of the left-side, and then merge the new left-side with the right-side:
  208. root = mergeTreaps(mergeTreaps(parts.left, storeTreap), parts.right).root;
  209. }
  210.  
  211. bool removeElementByPos(num_items oldPos) {
  212. //If the index is too big or too small, we can't remove it:
  213. if (oldPos+1 > getSize()) return false;
  214. if (oldPos < 0) return false;
  215.  
  216. //Split treap up into a left-side which has the first (oldPos+1) elements:
  217. treap_pair<item_key, item_value> parts = splitByPos(oldPos+1);
  218. //Now, separate out the first oldPos elements from this left-side in order to isolate the (oldPos)th element:
  219. treap_pair<item_key, item_value> parts2 = parts.left.splitByPos(oldPos);
  220. //Merge treaps back together without the isolated element:
  221. root = mergeTreaps(parts2.left, parts.right).root;
  222.  
  223. return true;
  224. }
  225.  
  226. treap getNodeAtPos(num_items pos) {
  227. //If the index is too big or too small, we can't find its value:
  228. if (pos < 0) return nullptr;
  229. if (pos > getSize()) return nullptr;
  230.  
  231. treap<item_key, item_value> curTreap = *this;
  232. //Keep looking for the treap whose root is the (pos)th element:
  233. while (curTreap.root->left.getSize() != pos) {
  234. //If the left subtree has less than pos elements, then the (pos)th element must be in the right subtree.
  235. //Also, adjust pos accordingly.
  236. if (curTreap.root->left.getSize() < pos) {
  237. pos -= curTreap.root->left.getSize()+1;
  238. curTreap = curTreap.root->right;
  239. }
  240. //Otherwise, the (pos)th element must be in the left subtree.
  241. else curTreap = curTreap.root->left;
  242.  
  243. if (curTreap.root == nullptr) puts("Treap size values are corrupted"), exit(1);
  244. }
  245. //Finally, return the treap that we just found:
  246. return curTreap;
  247. }
  248. };
  249.  
  250.  
  251. const num_items MAX_SPACE = 4000000;
  252. template <class item_key, class item_value> node<item_key, item_value> space[MAX_SPACE];
  253. template <class item_key, class item_value> num_items numSpaceUsed;
  254. template <class item_key, class item_value> treap<item_key, item_value> newTreapNode(item_key key, item_value value) {
  255. if (numSpaceUsed<item_key, item_value> >= MAX_SPACE) puts("Ran out of treap node space"), exit(1);
  256.  
  257. space<item_key, item_value>[numSpaceUsed<item_key, item_value>].priority = rand();
  258. space<item_key, item_value>[numSpaceUsed<item_key, item_value>].key = key;
  259. space<item_key, item_value>[numSpaceUsed<item_key, item_value>].value = value;
  260. space<item_key, item_value>[numSpaceUsed<item_key, item_value>].left = treap<item_key, item_value>();
  261. space<item_key, item_value>[numSpaceUsed<item_key, item_value>].right = treap<item_key, item_value>();
  262.  
  263. treap<item_key, item_value> newNode(space<item_key, item_value>+numSpaceUsed<item_key, item_value>);
  264. newNode.updateProperties();
  265.  
  266. numSpaceUsed<item_key, item_value>++;
  267. return newNode;
  268. }
  269. }
  270.  
  271. namespace range_tree {
  272. template<class item_type, ssize_t dimension, ssize_t level> struct subtree {
  273. treap::treap<item_type, subtree<item_type, dimension, level-1>> internalTree;
  274. };
  275.  
  276. template <class item_type, ssize_t dimension> using tree = subtree<item_type, dimension, dimension>;
  277.  
  278. template<class item_type, ssize_t dimension> struct subtree<item_type, dimension, 2> {
  279. treap::treap<item_type, treap::treap<item_type, int32_t>> internalTree;
  280.  
  281. subtree(num_items numItems, std::array<item_type, dimension> *points) {
  282. std::sort(
  283. }
  284. };
  285. }
  286.  
  287. int main() {
  288. range_tree::tree<int32_t, 10> test;
  289. range_tree::subtree<int32_t, 10, 2> test2 = test.internalTree.root->value.internalTree.root->value.internalTree.root->value.internalTree.root->value.internalTree.root->value.internalTree.root->value.internalTree.root->value.internalTree.root->value;
  290.  
  291. /* num_items NUM_ITEMS = 10;
  292. int32_t arr[NUM_ITEMS] = {1, 2, 3, 4, 6, 9, 10, 1203, 2000, 3000};
  293. int32_t arr2[NUM_ITEMS] = {1, 23, 31, -4, 5, 2, 56, 23, 1, 3};
  294. treap::treap<int32_t, int32_t> test(NUM_ITEMS, arr);
  295. for (int i = 0; i < test.getSize(); i++) {
  296. printf("%d\n", test.getNodeAtPos(i).root->value);
  297. } // */
  298. exit(0);
  299. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement