1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| struct Node { std::array<Node*, 2> next{}; int icnt = 0; };
void insert(Node*& p, int val, int bit = 30) { if (!p) { p = new Node(); } p->icnt++; if (bit == -1) return; int c = (val >> bit) & 1; insert(p->next[c], val, bit - 1); }
bool extract(Node*& p, int val, int bit = 30) { if (!p) return false; if (bit >= 0) { int c = (val >> bit) & 1; if (!extract(p->next[c], val, bit - 1)) { return false; } } if (--p->icnt == 0) { delete p; p = nullptr; } return true; }
i64 count_less_than(Node* p, int P, int L, int bit = 30) { if (!p || bit == -1) return 0; int c = (P >> bit) & 1; i64 ans = 0; if ((L >> bit) & 1) { if (p->next[c]) { ans += p->next[c]->icnt; } if (p->next[c ^ 1]) { ans += count_less_than(p->next[c ^ 1], P, L, bit - 1); } } else { if (p->next[c]) { ans += count_less_than(p->next[c], P, L, bit - 1); } } return ans; }
i64 get_kth_min(Node* p, int P, int k, int bit = 30) { if (!p || bit == -1) return 0; int c = (P >> bit) & 1; int cnt_pref = (p->next[c] ? p->next[c]->icnt : 0); if (k <= cnt_pref) { return get_kth_min(p->next[c], P, k, bit - 1); } else { return get_kth_min(p->next[c ^ 1], P, k - cnt_pref, bit - 1) + (1LL << bit); } }
i64 get_min_val(Node* p, int val, int bit = 30) { if (!p || bit == -1) return 0; int c = (val >> bit) & 1; if (p->next[c]) { return get_min_val(p->next[c], val, bit - 1); } return get_min_val(p->next[c ^ 1], val, bit - 1) + (1LL << bit); }
i64 get_max_val(Node* p, int val, int bit = 30) { if (!p || bit == -1) return 0; int c = (val >> bit) & 1; if (p->next[c ^ 1]) { return get_max_val(p->next[c ^ 1], val, bit - 1) + (1LL << bit); } return get_max_val(p->next[c], val, bit - 1); }
i64 get_min_two_trees(Node* u, Node* v, int bit = 30) { if (bit == -1) return 0; i64 res = 1LL << 60; if ((u->next[0] && v->next[0]) || (u->next[1] && v->next[1])) { if (u->next[0] && v->next[0]) { chmin(res, get_min_two_trees(u->next[0], v->next[0], bit - 1)); } if (u->next[1] && v->next[1]) { chmin(res, get_min_two_trees(u->next[1], v->next[1], bit - 1)); } } else { if (u->next[0] && v->next[1]) { chmin(res, get_min_two_trees(u->next[0], v->next[1], bit - 1) + (1LL << bit)); } if (u->next[1] && v->next[0]) { chmin(res, get_min_two_trees(u->next[1], v->next[0], bit - 1) + (1LL << bit)); } } return res; }
i64 get_max_two_trees(Node* u, Node* v, int bit = 30) { if (bit == -1) return 0; i64 res = -1; if ((u->next[0] && v->next[1]) || (u->next[1] && v->next[0])) { if (u->next[0] && v->next[1]) { chmax(res, get_max_two_trees(u->next[0], v->next[1], bit - 1) + (1LL << bit)); } if (u->next[1] && v->next[0]) { chmax(res, get_max_two_trees(u->next[1], v->next[0], bit - 1) + (1LL << bit)); } } else { if (u->next[0] && v->next[0]) { chmax(res, get_max_two_trees(u->next[0], v->next[0], bit - 1)); } if (u->next[1] && v->next[1]) { chmax(res, get_max_two_trees(u->next[1], v->next[1], bit - 1)); } } return res; }
|