|
| 1 | +// persistent segment trees |
| 2 | +// Codechef MAY17 Long Challenge |
| 3 | +// Problem Name: Gotham PD |
| 4 | +// Problem Code : GPD |
| 5 | +#include <bits/stdc++.h> |
| 6 | +#define ll long long |
| 7 | +#define ull unsigned long long |
| 8 | +#define vi vector<ll> |
| 9 | +#define pp pair<ll,ll> |
| 10 | +#define mp make_pair |
| 11 | +#define PI acos(-1.0) |
| 12 | +#define all(v) v.begin(),v.end() |
| 13 | +#define pb push_back |
| 14 | +#define FOR(i,a,b) for(i=a;i<b;i++) |
| 15 | +#define FREV(i,a,b) for(i=a;i>=b;i--) |
| 16 | +#define INF 1e18 |
| 17 | + |
| 18 | +#ifndef ONLINE_JUDGE |
| 19 | +#define gc getchar |
| 20 | +#define pc putchar |
| 21 | +#else |
| 22 | +#define gc getchar_unlocked |
| 23 | +#define pc putchar_unlocked |
| 24 | +#endif |
| 25 | + |
| 26 | +using namespace std; |
| 27 | + |
| 28 | +int read_int() { |
| 29 | + char c = gc(); |
| 30 | + while((c < '0' || c > '9') && c != '-') c = gc(); |
| 31 | + int ret = 0, neg = 0; |
| 32 | + if (c == '-') neg = 1, c = gc(); |
| 33 | + while(c >= '0' && c <= '9') { |
| 34 | + ret = 10 * ret + c - 48; |
| 35 | + c = gc(); |
| 36 | + } |
| 37 | + return neg ? -ret : ret; |
| 38 | +} |
| 39 | + |
| 40 | +ll read_ll() { |
| 41 | + char c = gc(); |
| 42 | + while((c < '0' || c > '9') && c != '-') c = gc(); |
| 43 | + ll ret = 0; |
| 44 | + int neg = 0; |
| 45 | + if (c == '-') neg = 1, c = gc(); |
| 46 | + while(c >= '0' && c <= '9') { |
| 47 | + ret = 10 * ret + c - 48; |
| 48 | + c = gc(); |
| 49 | + } |
| 50 | + return neg ? -ret : ret; |
| 51 | +} |
| 52 | + |
| 53 | +struct node { |
| 54 | + node* left; |
| 55 | + node* right; |
| 56 | + |
| 57 | + node() { |
| 58 | + this->left = NULL; |
| 59 | + this->right = NULL; |
| 60 | + } |
| 61 | +}; |
| 62 | + |
| 63 | +vi parent(300005); |
| 64 | +string bit_string; |
| 65 | +vector<node*> tree_roots; |
| 66 | +map<ll,ll> get_index_from_id; |
| 67 | + |
| 68 | +void create_tree(node* &root, ll key, ll parent_index) { |
| 69 | + node* temp = root; |
| 70 | + bit_string = bitset<32>(key).to_string(); |
| 71 | + int i; |
| 72 | + if (parent_index == -1) { |
| 73 | + FOR(i,0,32) { |
| 74 | + if (bit_string[i] == '0') { |
| 75 | + root->left = new node(); |
| 76 | + root = root->left; |
| 77 | + } |
| 78 | + else { |
| 79 | + root->right = new node(); |
| 80 | + root = root->right; |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + else { |
| 85 | + node* parent_root = tree_roots[parent_index]; |
| 86 | + FOR(i,0,32) { |
| 87 | + if (bit_string[i] == '0') { |
| 88 | + root->left = new node(); |
| 89 | + if (parent_root != NULL) { |
| 90 | + root->right = parent_root->right; |
| 91 | + parent_root = parent_root->left; |
| 92 | + } |
| 93 | + root = root->left; |
| 94 | + |
| 95 | + } |
| 96 | + else { |
| 97 | + root->right = new node(); |
| 98 | + if (parent_root != NULL) { |
| 99 | + root->left = parent_root->left; |
| 100 | + parent_root = parent_root->right; |
| 101 | + } |
| 102 | + root = root->right; |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | + root = temp; |
| 107 | +} |
| 108 | + |
| 109 | +void solve(ll v, ll k, ll &min_answer, ll &max_answer) { |
| 110 | + bit_string = bitset<32>(k).to_string(); |
| 111 | + node* root = tree_roots[v]; |
| 112 | + ll minim = 0, maxim = 0; |
| 113 | + int i; |
| 114 | + |
| 115 | + // find max |
| 116 | + FREV(i,31,0) { |
| 117 | + if (bit_string[31-i] == '0') { |
| 118 | + if (root->right != NULL) { |
| 119 | + maxim += (1<<i); |
| 120 | + root = root->right; |
| 121 | + } |
| 122 | + else { |
| 123 | + root = root->left; |
| 124 | + } |
| 125 | + } |
| 126 | + else { |
| 127 | + if (root->left != NULL) { |
| 128 | + maxim += (1<<i); |
| 129 | + root = root->left; |
| 130 | + } |
| 131 | + else { |
| 132 | + root = root->right; |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | + |
| 137 | + root = tree_roots[v]; |
| 138 | + |
| 139 | + // find min |
| 140 | + FREV(i,31,0) { |
| 141 | + if (bit_string[31-i] == '0') { |
| 142 | + if (root->left != NULL) { |
| 143 | + root = root->left; |
| 144 | + } |
| 145 | + else { |
| 146 | + minim += (1<<i); |
| 147 | + root = root->right; |
| 148 | + } |
| 149 | + } |
| 150 | + else { |
| 151 | + if (root->right != NULL) { |
| 152 | + root = root->right; |
| 153 | + } |
| 154 | + else { |
| 155 | + minim += (1<<i); |
| 156 | + root = root->left; |
| 157 | + } |
| 158 | + } |
| 159 | + } |
| 160 | + |
| 161 | + min_answer = minim; |
| 162 | + max_answer = maxim; |
| 163 | +} |
| 164 | + |
| 165 | +int main() { |
| 166 | + ll i,u,v,r,r_key,k,q,n,min_answer,max_answer,index=0; |
| 167 | + int t; |
| 168 | + n = read_ll(); |
| 169 | + q = read_ll(); |
| 170 | + r = read_ll(); |
| 171 | + r_key = read_ll(); |
| 172 | + tree_roots.pb(new node()); |
| 173 | + get_index_from_id[r] = index; |
| 174 | + parent[index] = -1; |
| 175 | + create_tree(tree_roots[index], r_key, -1); |
| 176 | + index++; |
| 177 | + FOR(i,0,n-1) { |
| 178 | + u = read_ll(); |
| 179 | + v = read_ll(); |
| 180 | + k = read_ll(); |
| 181 | + |
| 182 | + tree_roots.pb(new node()); |
| 183 | + |
| 184 | + get_index_from_id[u] = index; |
| 185 | + parent[index] = get_index_from_id[v]; |
| 186 | + create_tree(tree_roots[index], k, parent[index]); |
| 187 | + index++; |
| 188 | + } |
| 189 | + |
| 190 | + ll last_answer = 0; |
| 191 | + FOR(i,0,q) { |
| 192 | + t = read_int(); |
| 193 | + t ^= last_answer; |
| 194 | + |
| 195 | + if(t == 0) { |
| 196 | + v = read_ll(); |
| 197 | + u = read_ll(); |
| 198 | + k = read_ll(); |
| 199 | + |
| 200 | + u ^= last_answer; |
| 201 | + v ^= last_answer; |
| 202 | + k ^= last_answer; |
| 203 | + |
| 204 | + tree_roots.pb(new node()); |
| 205 | + |
| 206 | + get_index_from_id[u] = index; |
| 207 | + parent[index] = get_index_from_id[v]; |
| 208 | + create_tree(tree_roots[index], k, parent[index]);; |
| 209 | + index++; |
| 210 | + } |
| 211 | + else { |
| 212 | + v = read_ll(); |
| 213 | + k = read_ll(); |
| 214 | + |
| 215 | + v ^= last_answer; |
| 216 | + k ^= last_answer; |
| 217 | + |
| 218 | + solve(get_index_from_id[v],k,min_answer,max_answer); |
| 219 | + printf("%lld %lld\n", min_answer, max_answer); |
| 220 | + |
| 221 | + last_answer = min_answer^max_answer; |
| 222 | + } |
| 223 | + } |
| 224 | + return 0; |
| 225 | +} |
0 commit comments