Use this to learn the idea, then write your own version.
1struct Node {2 Node(int v) : val(v), subXor(v) {}3 int val;4 int subXor;5 int sz = 1;6 int rev = false;7 int prior = rand();8 Node* l = nullptr;9 Node* r = nullptr;10};11 12class AVLTree {13 public:14 AVLTree(const vector<int>& nums) : root(nullptr) {15 build(nums);16 }17 18 void updateValue(int index, int val) {19 Node* l = nullptr;20 Node* r = nullptr;21 Node* m = nullptr;22 split(root, index, l, r);23 split(r, 1, m, r);24 if (m != nullptr)25 m->val = val;26 update(m);27 root = merge(merge(l, m), r);28 }29 30 int rangeXor(int left, int right) {31 Node* l = nullptr;32 Node* m = nullptr;33 Node* r = nullptr;34 split(root, left, l, r);35 split(r, right - left + 1, m, r);36 const int res = getXor(m);37 root = merge(merge(l, m), r);38 return res;39 }40 41 void reverseRange(int left, int right) {42 Node* l = nullptr;43 Node* m = nullptr;44 Node* r = nullptr;45 split(root, left, l, r);46 split(r, right - left + 1, m, r);47 if (m != nullptr)48 m->rev = !m->rev;49 root = merge(merge(l, m), r);50 }51 52 private:53 Node* root;54 55 void build(const vector<int>& nums) {56 for (const int num : nums)57 root = merge(root, new Node(num));58 }59 60 int getSize(Node* t) {61 return t ? t->sz : 0;62 }63 64 int getXor(Node* t) {65 return t ? t->subXor : 0;66 }67 68 void push(Node* t) {69 if (t == nullptr || !t->rev)70 return;71 swap(t->l, t->r);72 if (t->l != nullptr)73 t->l->rev ^= 1;74 if (t->r != nullptr)75 t->r->rev ^= 1;76 t->rev = false;77 }78 79 void update(Node* t) {80 if (t == nullptr)81 return;82 t->sz = 1 + getSize(t->l) + getSize(t->r);83 t->subXor = t->val ^ getXor(t->l) ^ getXor(t->r);84 }85 86 void split(Node* t, int k, Node*& l, Node*& r) {87 if (t == nullptr)88 return void(l = r = nullptr);89 push(t);90 if (getSize(t->l) >= k) {91 split(t->l, k, l, t->l);92 r = t;93 } else {94 split(t->r, k - getSize(t->l) - 1, t->r, r);95 l = t;96 }97 update(t);98 }99 100 Node* merge(Node* l, Node* r) {101 push(l);102 push(r);103 if (l == nullptr || r == nullptr)104 return l == nullptr ? r : l;105 if (l->prior > r->prior) {106 l->r = merge(l->r, r);107 update(l);108 return l;109 } else {110 r->l = merge(l, r->l);111 update(r);112 return r;113 }114 }115};116 117class Solution {118 public:119 vector<int> getResults(vector<int>& nums, vector<vector<int>>& queries) {120 AVLTree tree(nums);121 vector<int> ans;122 123 for (const vector<int>& query : queries) {124 const int type = query[0];125 if (type == 1)126 tree.updateValue(query[1], query[2]);127 else if (type == 2)128 ans.push_back(tree.rangeXor(query[1], query[2]));129 else if (type == 3)130 tree.reverseRange(query[1], query[2]);131 }132 133 return ans;134 }135};136