fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long int
  4. #define endl "\n"
  5.  
  6. struct Node
  7. {
  8. ll data = -1;
  9. Node *left, *right; // Pointers to left child and right child
  10.  
  11. Node() // Constructor
  12. {
  13. data = -1;
  14. left = nullptr;
  15. right = nullptr;
  16. }
  17. Node(const ll &val)
  18. {
  19. data = val;
  20. left = nullptr;
  21. right = nullptr;
  22. }
  23.  
  24. void createChildren() // Construct Childs
  25. {
  26. if (left == nullptr)
  27. left = new Node();
  28. if (right == nullptr)
  29. right = new Node();
  30. }
  31. ~Node() // Destructor. Notice the "~" character before the struct name.
  32. {
  33. delete left;
  34. delete right;
  35. left = nullptr;
  36. right = nullptr;
  37. }
  38. };
  39.  
  40. class binaryTrie
  41. {
  42. private:
  43. Node *root = new Node();
  44. ll rootHeight = 32;
  45. Node *adjustedRoot = nullptr; // First diverging Node
  46. ll adjustedRootHeight = UINT_MAX;
  47.  
  48. public:
  49. void insert(ll x)
  50. {
  51. Node *currentNode = root;
  52.  
  53. for (int k = 31; k >= 0; k--)
  54. {
  55. if (((x >> k) & 1) == 0) // curr bit is 0 - left
  56. {
  57. if (currentNode->left == nullptr)
  58. currentNode->left = new Node();
  59.  
  60. currentNode = currentNode->left;
  61. }
  62. else // curr bit is 1 - right
  63. {
  64. if (currentNode->right == nullptr)
  65. currentNode->right = new Node();
  66.  
  67. currentNode = currentNode->right;
  68. }
  69. }
  70.  
  71. currentNode->data = x;
  72. }
  73.  
  74. int getMin()
  75. {
  76. // Reconstruct value OR'ing with mask as go right
  77. // Always go left unless have to go right
  78. Node *currentNode = root;
  79. ll min = 0;
  80. for (ll mask = (1LL << 31); mask != 0; mask >>= 1)
  81. {
  82. if (currentNode->left)
  83. currentNode = currentNode->left;
  84. else
  85. {
  86. min |= mask;
  87. currentNode = currentNode->right;
  88. }
  89. }
  90.  
  91. return min;
  92. }
  93.  
  94. vector<ll> getMins()
  95. {
  96. vector<ll> mins;
  97. Node *currentNode = adjustedRoot->left;
  98. stack<Node *> treeStack;
  99. treeStack.push(currentNode);
  100.  
  101. while (!treeStack.empty())
  102. {
  103. currentNode = treeStack.top();
  104. treeStack.pop();
  105.  
  106. if (currentNode->data != -1)
  107. mins.push_back(currentNode->data);
  108.  
  109. if (currentNode->left)
  110. treeStack.push(currentNode->left);
  111.  
  112. if (currentNode->right)
  113. treeStack.push(currentNode->right);
  114. }
  115.  
  116. return mins;
  117. }
  118.  
  119. int getMax()
  120. {
  121. // Reconstruct value OR'ing with mask as go right
  122. // Always go right unless have to go left
  123. Node *currentNode = root;
  124. ll max = 0;
  125. for (ll mask = (1LL << 31); mask != 0; mask >>= 1)
  126. {
  127. if (currentNode->right)
  128. {
  129. max |= mask;
  130. currentNode = currentNode->right;
  131. }
  132. else
  133. currentNode = currentNode->left;
  134. }
  135.  
  136. return max;
  137. }
  138.  
  139. int getClosest(ll x)
  140. {
  141. // Reconstruct value OR'ing with mask as go right
  142. // Always go right unless have to go left
  143. Node *currentNode = root;
  144. ll closest = 0;
  145.  
  146. for (ll mask = (1LL << 31); mask != 0; mask >>= 1)
  147. {
  148. ll applyMask = mask & x;
  149. if (applyMask) // we desire to go right in priority
  150. {
  151. if (currentNode->right)
  152. {
  153. closest |= mask;
  154. currentNode = currentNode->right;
  155. }
  156. else
  157. currentNode = currentNode->left;
  158. }
  159. else // we desire to go to the left in priority
  160. {
  161. if (currentNode->left)
  162. currentNode = currentNode->left;
  163. else
  164. {
  165. closest |= mask;
  166. currentNode = currentNode->right;
  167. }
  168. }
  169. }
  170.  
  171. return closest;
  172. }
  173.  
  174. bool setAdjustedRoot()
  175. {
  176. Node *currentNode = root;
  177. ll count = 0;
  178.  
  179. // First node with both valid kiddoes
  180. while (currentNode->left == nullptr || currentNode->right == nullptr)
  181. {
  182. count++;
  183.  
  184. if (count == rootHeight)
  185. return false;
  186.  
  187. if (currentNode->left)
  188. currentNode = currentNode->left;
  189. else
  190. currentNode = currentNode->right;
  191. }
  192.  
  193. adjustedRoot = currentNode;
  194. adjustedRootHeight = rootHeight - count;
  195. return true;
  196. }
  197. };
  198.  
  199. int main()
  200. {
  201. ios_base::sync_with_stdio(false);
  202. cin.tie(nullptr);
  203. int t = 1;
  204. ll N;
  205. // cin >> t;
  206. while (t--)
  207. {
  208. cin >> N;
  209. vector<ll> a(N);
  210. for (int i{}; i < N; i++)
  211. cin >> a[i];
  212.  
  213. binaryTrie tree;
  214.  
  215. // Insert Values
  216. for (const ll &x : a)
  217. tree.insert(x);
  218.  
  219. bool set = tree.setAdjustedRoot();
  220. if (!set)
  221. return cout << 0, 0; // No adjustable root set, means only inserted same value, max Xor is 0
  222.  
  223. ll treeMin = tree.getMin();
  224. ll treeMax = tree.getMax();
  225.  
  226. // go left to right, 0 means bits align, stop at soon as we see a 1, means LCS
  227. ll diverge = treeMin ^ treeMax;
  228. ll countOnes = 31;
  229.  
  230. ll mask = (1LL << 31);
  231. while ((mask & diverge) == 0)
  232. {
  233. countOnes--;
  234. mask >>= 1;
  235. }
  236.  
  237. ll globalMin = LLONG_MAX;
  238. vector<ll> mins = tree.getMins();
  239. for (const ll &m : mins)
  240. {
  241. ll targetMax = m ^ mask;
  242. ll closestMax = tree.getClosest(targetMax);
  243. globalMin = min(globalMin, m ^ closestMax);
  244. }
  245. cout << globalMin;
  246. }
  247. return 0;
  248. }
  249.  
Success #stdin #stdout #stderr 0.29s 40772KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected symbol in "using namespace"
Execution halted