├── COT.cpp ├── DQUERY.cpp ├── MKTHNUM.cpp ├── bigint.cpp └── qtree.cpp /COT.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | By Anudeep Nekkanti 3 | Editorial at www.blog.anudeep.com/persistent-segment-trees-explained-with-spoj-problems 4 | Question at http://www.spoj.com/problems/COT/ 5 | O( (N+M) * log N ) 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | #define sz size() 15 | #define pb push_back 16 | #define rep(i,n) for(int i=0;i=b; i--) 18 | 19 | #define N 111111 20 | #define LN 19 21 | int v[N], pa[N][LN], RM[N], depth[N], maxi = 0; 22 | vector adj[N]; 23 | map M; 24 | 25 | struct node 26 | { 27 | int count; 28 | node *left, *right; 29 | 30 | node(int count, node *left, node *right): 31 | count(count), left(left), right(right) {} 32 | 33 | node* insert(int l, int r, int w); 34 | }; 35 | 36 | node *null = new node(0, NULL, NULL); //see line 135 37 | 38 | node * node::insert(int l, int r, int w) 39 | { 40 | if(l <= w && w < r) 41 | { 42 | // With in the range, we need a new node 43 | if(l+1 == r) 44 | { 45 | return new node(this->count+1, null, null); 46 | } 47 | 48 | int m = (l+r)>>1; 49 | 50 | return new node(this->count+1, this->left->insert(l, m, w), this->right->insert(m, r, w)); 51 | } 52 | 53 | // Out of range, we can use previous tree node. 54 | return this; 55 | } 56 | 57 | node *root[N]; 58 | void dfs(int cur, int prev) 59 | { 60 | pa[cur][0] = prev; 61 | depth[cur] = (prev == -1 ? 0 : depth[prev] + 1); 62 | 63 | // Construct the segment tree for this node using parent segment tree 64 | // This is the formula we derived 65 | root[cur] = ( prev == -1 ? null : root[prev] )->insert( 0, maxi, M[v[cur]] ); 66 | 67 | rep(i, adj[cur].sz) 68 | if(adj[cur][i] != prev) 69 | dfs(adj[cur][i], cur); 70 | } 71 | 72 | int LCA(int u, int v) 73 | { 74 | if(depth[u] < depth[v]) 75 | return LCA(v, u); 76 | 77 | int diff = depth[u] - depth[v]; 78 | 79 | rep(i, LN) 80 | if((diff>>i) & 1) 81 | u = pa[u][i]; 82 | 83 | if(u != v) 84 | { 85 | fd(i, LN-1, 0) 86 | if(pa[u][i] != pa[v][i]) 87 | { 88 | u = pa[u][i]; 89 | v = pa[v][i]; 90 | } 91 | u = pa[u][0]; 92 | } 93 | 94 | return u; 95 | } 96 | 97 | int query(node *a, node *b, node *c, node *d, int l, int r, int k) 98 | { 99 | if(l+1 == r) 100 | { 101 | return l; 102 | } 103 | 104 | // This is the formula we derived 105 | int count = a->left->count + b->left->count - c->left->count - d->left->count; 106 | int m = (l+r)>>1; 107 | 108 | // We have enough on left, so go left 109 | if(count >= k) 110 | return query(a->left, b->left, c->left, d->left, l, m, k); 111 | 112 | // We do not have enough on left, go right, remove left elements count 113 | return query(a->right, b->right, c->right, d->right, m, r, k - count); 114 | } 115 | 116 | int main() 117 | { 118 | int n, m; 119 | 120 | scanf("%d%d", &n, &m); 121 | 122 | rep(i, n) 123 | { 124 | scanf("%d", &v[i]); 125 | M[v[i]]; 126 | } 127 | 128 | maxi = 0; 129 | for( map :: iterator it = M.begin(); it != M.end(); it++ ) 130 | { 131 | M[it->first] = maxi; 132 | RM[maxi] = it->first; 133 | maxi++; 134 | } 135 | 136 | // We compressed the given weights into the range [0..n) 137 | 138 | rep(i, n-1) 139 | { 140 | int u, v; 141 | scanf("%d%d", &u, &v); 142 | u--; v--; 143 | adj[u].pb(v); 144 | adj[v].pb(u); 145 | } 146 | 147 | // Root the tree at some node. 148 | memset(pa, -1, sizeof pa); 149 | null->left = null->right = null; 150 | dfs(0, -1); 151 | 152 | // Build jump table for LCA in O( log N ) 153 | rep(i, LN-1) 154 | rep(j, n) 155 | if(pa[j][i] != -1) 156 | pa[j][i+1] = pa[pa[j][i]][i]; 157 | 158 | while(m--) 159 | { 160 | int u, v, k; 161 | scanf("%d%d%d", &u, &v, &k); 162 | u--; v--; 163 | 164 | int lca = LCA(u, v); 165 | // Four nodes we spoke about are u, v, lca, parent(lca) 166 | int ans = query(root[u], root[v], root[lca], (pa[lca][0] == -1 ? null : root[ pa[lca][0] ]), 0, maxi, k); 167 | 168 | // Reverse Map the values, that is, uncompress 169 | printf("%d\n", RM[ans]); 170 | } 171 | } -------------------------------------------------------------------------------- /DQUERY.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | By Anudeep Nekkanti 3 | Editorial at http://blog.anudeep2011.com/mos-algorithm/ 4 | Question at http://www.spoj.com/problems/DQUERY/ 5 | O( (N+M) * sqrt N ) 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | #define N 311111 13 | #define A 1111111 14 | #define BLOCK 555 // ~sqrt(N) 15 | 16 | int cnt[A], a[N], ans[N], answer = 0; 17 | 18 | struct node { 19 | int L, R, i; 20 | }q[N]; 21 | 22 | bool cmp(node x, node y) { 23 | if(x.L/BLOCK != y.L/BLOCK) { 24 | // different blocks, so sort by block. 25 | return x.L/BLOCK < y.L/BLOCK; 26 | } 27 | // same block, so sort by R value 28 | return x.R < y.R; 29 | } 30 | 31 | void add(int position) { 32 | cnt[a[position]]++; 33 | if(cnt[a[position]] == 1) { 34 | answer++; 35 | } 36 | } 37 | 38 | void remove(int position) { 39 | cnt[a[position]]--; 40 | if(cnt[a[position]] == 0) { 41 | answer--; 42 | } 43 | } 44 | 45 | int main() { 46 | int n; 47 | scanf("%d", &n); 48 | for(int i=0; i L) { 69 | add(currentL-1); 70 | currentL--; 71 | } 72 | while(currentR <= R) { 73 | add(currentR); 74 | currentR++; 75 | } 76 | while(currentR > R+1) { 77 | remove(currentR-1); 78 | currentR--; 79 | } 80 | ans[q[i].i] = answer; 81 | } 82 | 83 | for(int i=0; i 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | #define sz size() 15 | #define pb push_back 16 | #define rep(i,n) for(int i=0;i=b; i--) 18 | 19 | #define N 111111 20 | 21 | struct node 22 | { 23 | int count; 24 | node *left, *right; 25 | 26 | node(int count, node *left, node *right): 27 | count(count), left(left), right(right) {} 28 | 29 | node* insert(int l, int r, int w); 30 | }; 31 | 32 | node *null = new node(0, NULL, NULL); //see line 135 33 | 34 | node * node::insert(int l, int r, int w) 35 | { 36 | if(l <= w && w < r) 37 | { 38 | // With in the range, we need a new node 39 | if(l+1 == r) 40 | { 41 | return new node(this->count+1, null, null); 42 | } 43 | 44 | int m = (l+r)>>1; 45 | 46 | return new node(this->count+1, this->left->insert(l, m, w), this->right->insert(m, r, w)); 47 | } 48 | 49 | // Out of range, we can use previous tree node. 50 | return this; 51 | } 52 | 53 | int query(node *a, node *b, int l, int r, int k) 54 | { 55 | if(l+1 == r) 56 | { 57 | return l; 58 | } 59 | 60 | int m = (l+r)>>1; 61 | int count = a->left->count - b->left->count; 62 | if(count >= k) 63 | return query(a->left, b->left, l, m, k); 64 | 65 | return query(a->right, b->right, m, r, k-count); 66 | } 67 | 68 | int a[N], RM[N]; 69 | node *root[N]; 70 | int main() 71 | { 72 | int n, m; 73 | scanf("%d%d", &n, &m); 74 | 75 | map M; 76 | rep(i, n) 77 | { 78 | scanf("%d", &a[i]); 79 | M[a[i]]; 80 | } 81 | 82 | int maxi = 0; 83 | 84 | for(map :: iterator it = M.begin(); it != M.end(); it++) 85 | { 86 | M[it->first] = maxi; 87 | RM[maxi] = it->first; 88 | maxi++; 89 | } 90 | 91 | null->left = null->right = null; 92 | rep(i, n) 93 | { 94 | // Build a tree for each prefix using segment tree of previous prefix 95 | root[i] = (i == 0 ? null : root[i-1])->insert( 0, maxi, M[a[i]] ); 96 | } 97 | 98 | while(m--) 99 | { 100 | int u, v, k; 101 | scanf("%d%d%d", &u, &v, &k); 102 | u--; v--; 103 | 104 | int ans = query(root[v], (u==0?null:root[u-1]), 0, maxi, k); 105 | printf("%d\n", RM[ans]); 106 | } 107 | } -------------------------------------------------------------------------------- /bigint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int base = 1000000000; 7 | const int base_digits = 9; 8 | 9 | struct bigint { 10 | vector a; 11 | int sign; 12 | 13 | bigint() : 14 | sign(1) { 15 | } 16 | 17 | bigint(long long v) { 18 | *this = v; 19 | } 20 | 21 | bigint(const string &s) { 22 | read(s); 23 | } 24 | 25 | void operator=(const bigint &v) { 26 | sign = v.sign; 27 | a = v.a; 28 | } 29 | 30 | void operator=(long long v) { 31 | sign = 1; 32 | if (v < 0) 33 | sign = -1, v = -v; 34 | for (; v > 0; v = v / base) 35 | a.push_back(v % base); 36 | } 37 | 38 | bigint operator+(const bigint &v) const { 39 | if (sign == v.sign) { 40 | bigint res = v; 41 | 42 | for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) { 43 | if (i == (int) res.a.size()) 44 | res.a.push_back(0); 45 | res.a[i] += carry + (i < (int) a.size() ? a[i] : 0); 46 | carry = res.a[i] >= base; 47 | if (carry) 48 | res.a[i] -= base; 49 | } 50 | return res; 51 | } 52 | return *this - (-v); 53 | } 54 | 55 | bigint operator-(const bigint &v) const { 56 | if (sign == v.sign) { 57 | if (abs() >= v.abs()) { 58 | bigint res = *this; 59 | for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) { 60 | res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0); 61 | carry = res.a[i] < 0; 62 | if (carry) 63 | res.a[i] += base; 64 | } 65 | res.trim(); 66 | return res; 67 | } 68 | return -(v - *this); 69 | } 70 | return *this + (-v); 71 | } 72 | 73 | void operator*=(int v) { 74 | if (v < 0) 75 | sign = -sign, v = -v; 76 | for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) { 77 | if (i == (int) a.size()) 78 | a.push_back(0); 79 | long long cur = a[i] * (long long) v + carry; 80 | carry = (int) (cur / base); 81 | a[i] = (int) (cur % base); 82 | //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base)); 83 | } 84 | trim(); 85 | } 86 | 87 | bigint operator*(int v) const { 88 | bigint res = *this; 89 | res *= v; 90 | return res; 91 | } 92 | 93 | friend pair divmod(const bigint &a1, const bigint &b1) { 94 | int norm = base / (b1.a.back() + 1); 95 | bigint a = a1.abs() * norm; 96 | bigint b = b1.abs() * norm; 97 | bigint q, r; 98 | q.a.resize(a.a.size()); 99 | 100 | for (int i = a.a.size() - 1; i >= 0; i--) { 101 | r *= base; 102 | r += a.a[i]; 103 | int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()]; 104 | int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1]; 105 | int d = ((long long) base * s1 + s2) / b.a.back(); 106 | r -= b * d; 107 | while (r < 0) 108 | r += b, --d; 109 | q.a[i] = d; 110 | } 111 | 112 | q.sign = a1.sign * b1.sign; 113 | r.sign = a1.sign; 114 | q.trim(); 115 | r.trim(); 116 | return make_pair(q, r / norm); 117 | } 118 | 119 | bigint operator/(const bigint &v) const { 120 | return divmod(*this, v).first; 121 | } 122 | 123 | bigint operator%(const bigint &v) const { 124 | return divmod(*this, v).second; 125 | } 126 | 127 | void operator/=(int v) { 128 | if (v < 0) 129 | sign = -sign, v = -v; 130 | for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) { 131 | long long cur = a[i] + rem * (long long) base; 132 | a[i] = (int) (cur / v); 133 | rem = (int) (cur % v); 134 | } 135 | trim(); 136 | } 137 | 138 | bigint operator/(int v) const { 139 | bigint res = *this; 140 | res /= v; 141 | return res; 142 | } 143 | 144 | int operator%(int v) const { 145 | if (v < 0) 146 | v = -v; 147 | int m = 0; 148 | for (int i = a.size() - 1; i >= 0; --i) 149 | m = (a[i] + m * (long long) base) % v; 150 | return m * sign; 151 | } 152 | 153 | void operator+=(const bigint &v) { 154 | *this = *this + v; 155 | } 156 | void operator-=(const bigint &v) { 157 | *this = *this - v; 158 | } 159 | void operator*=(const bigint &v) { 160 | *this = *this * v; 161 | } 162 | void operator/=(const bigint &v) { 163 | *this = *this / v; 164 | } 165 | 166 | bool operator<(const bigint &v) const { 167 | if (sign != v.sign) 168 | return sign < v.sign; 169 | if (a.size() != v.a.size()) 170 | return a.size() * sign < v.a.size() * v.sign; 171 | for (int i = a.size() - 1; i >= 0; i--) 172 | if (a[i] != v.a[i]) 173 | return a[i] * sign < v.a[i] * sign; 174 | return false; 175 | } 176 | 177 | bool operator>(const bigint &v) const { 178 | return v < *this; 179 | } 180 | bool operator<=(const bigint &v) const { 181 | return !(v < *this); 182 | } 183 | bool operator>=(const bigint &v) const { 184 | return !(*this < v); 185 | } 186 | bool operator==(const bigint &v) const { 187 | return !(*this < v) && !(v < *this); 188 | } 189 | bool operator!=(const bigint &v) const { 190 | return *this < v || v < *this; 191 | } 192 | 193 | void trim() { 194 | while (!a.empty() && !a.back()) 195 | a.pop_back(); 196 | if (a.empty()) 197 | sign = 1; 198 | } 199 | 200 | bool isZero() const { 201 | return a.empty() || (a.size() == 1 && !a[0]); 202 | } 203 | 204 | bigint operator-() const { 205 | bigint res = *this; 206 | res.sign = -sign; 207 | return res; 208 | } 209 | 210 | bigint abs() const { 211 | bigint res = *this; 212 | res.sign *= res.sign; 213 | return res; 214 | } 215 | 216 | long long longValue() const { 217 | long long res = 0; 218 | for (int i = a.size() - 1; i >= 0; i--) 219 | res = res * base + a[i]; 220 | return res * sign; 221 | } 222 | 223 | friend bigint gcd(const bigint &a, const bigint &b) { 224 | return b.isZero() ? a : gcd(b, a % b); 225 | } 226 | friend bigint lcm(const bigint &a, const bigint &b) { 227 | return a / gcd(a, b) * b; 228 | } 229 | 230 | void read(const string &s) { 231 | sign = 1; 232 | a.clear(); 233 | int pos = 0; 234 | while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) { 235 | if (s[pos] == '-') 236 | sign = -sign; 237 | ++pos; 238 | } 239 | for (int i = s.size() - 1; i >= pos; i -= base_digits) { 240 | int x = 0; 241 | for (int j = max(pos, i - base_digits + 1); j <= i; j++) 242 | x = x * 10 + s[j] - '0'; 243 | a.push_back(x); 244 | } 245 | trim(); 246 | } 247 | 248 | friend istream& operator>>(istream &stream, bigint &v) { 249 | string s; 250 | stream >> s; 251 | v.read(s); 252 | return stream; 253 | } 254 | 255 | friend ostream& operator<<(ostream &stream, const bigint &v) { 256 | if (v.sign == -1) 257 | stream << '-'; 258 | stream << (v.a.empty() ? 0 : v.a.back()); 259 | for (int i = (int) v.a.size() - 2; i >= 0; --i) 260 | stream << setw(base_digits) << setfill('0') << v.a[i]; 261 | return stream; 262 | } 263 | 264 | static vector convert_base(const vector &a, int old_digits, int new_digits) { 265 | vector p(max(old_digits, new_digits) + 1); 266 | p[0] = 1; 267 | for (int i = 1; i < (int) p.size(); i++) 268 | p[i] = p[i - 1] * 10; 269 | vector res; 270 | long long cur = 0; 271 | int cur_digits = 0; 272 | for (int i = 0; i < (int) a.size(); i++) { 273 | cur += a[i] * p[cur_digits]; 274 | cur_digits += old_digits; 275 | while (cur_digits >= new_digits) { 276 | res.push_back(int(cur % p[new_digits])); 277 | cur /= p[new_digits]; 278 | cur_digits -= new_digits; 279 | } 280 | } 281 | res.push_back((int) cur); 282 | while (!res.empty() && !res.back()) 283 | res.pop_back(); 284 | return res; 285 | } 286 | 287 | typedef vector vll; 288 | 289 | static vll karatsubaMultiply(const vll &a, const vll &b) { 290 | int n = a.size(); 291 | vll res(n + n); 292 | if (n <= 32) { 293 | for (int i = 0; i < n; i++) 294 | for (int j = 0; j < n; j++) 295 | res[i + j] += a[i] * b[j]; 296 | return res; 297 | } 298 | 299 | int k = n >> 1; 300 | vll a1(a.begin(), a.begin() + k); 301 | vll a2(a.begin() + k, a.end()); 302 | vll b1(b.begin(), b.begin() + k); 303 | vll b2(b.begin() + k, b.end()); 304 | 305 | vll a1b1 = karatsubaMultiply(a1, b1); 306 | vll a2b2 = karatsubaMultiply(a2, b2); 307 | 308 | for (int i = 0; i < k; i++) 309 | a2[i] += a1[i]; 310 | for (int i = 0; i < k; i++) 311 | b2[i] += b1[i]; 312 | 313 | vll r = karatsubaMultiply(a2, b2); 314 | for (int i = 0; i < (int) a1b1.size(); i++) 315 | r[i] -= a1b1[i]; 316 | for (int i = 0; i < (int) a2b2.size(); i++) 317 | r[i] -= a2b2[i]; 318 | 319 | for (int i = 0; i < (int) r.size(); i++) 320 | res[i + k] += r[i]; 321 | for (int i = 0; i < (int) a1b1.size(); i++) 322 | res[i] += a1b1[i]; 323 | for (int i = 0; i < (int) a2b2.size(); i++) 324 | res[i + n] += a2b2[i]; 325 | return res; 326 | } 327 | 328 | bigint operator*(const bigint &v) const { 329 | vector a6 = convert_base(this->a, base_digits, 6); 330 | vector b6 = convert_base(v.a, base_digits, 6); 331 | vll a(a6.begin(), a6.end()); 332 | vll b(b6.begin(), b6.end()); 333 | while (a.size() < b.size()) 334 | a.push_back(0); 335 | while (b.size() < a.size()) 336 | b.push_back(0); 337 | while (a.size() & (a.size() - 1)) 338 | a.push_back(0), b.push_back(0); 339 | vll c = karatsubaMultiply(a, b); 340 | bigint res; 341 | res.sign = sign * v.sign; 342 | for (int i = 0, carry = 0; i < (int) c.size(); i++) { 343 | long long cur = c[i] + carry; 344 | res.a.push_back((int) (cur % 1000000)); 345 | carry = (int) (cur / 1000000); 346 | } 347 | res.a = convert_base(res.a, 6, base_digits); 348 | res.trim(); 349 | return res; 350 | } 351 | }; 352 | 353 | int main() 354 | { 355 | bigint a = bigint("1"); 356 | int b = 2; 357 | for(int i=1; i<100; i++) 358 | { 359 | a = a*b; 360 | } 361 | 362 | cout << a << endl; 363 | 364 | for(int i=1; i<99; i++) 365 | { 366 | a /= b; 367 | } 368 | 369 | cout << a << endl; 370 | } -------------------------------------------------------------------------------- /qtree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #define root 0 6 | #define N 10100 7 | #define LN 14 8 | 9 | vector adj[N], costs[N], indexx[N]; 10 | int baseArray[N], ptr; 11 | int chainNo, chainInd[N], chainHead[N], posInBase[N]; 12 | int depth[N], pa[LN][N], otherEnd[N], subsize[N]; 13 | int st[N*6], qt[N*6]; 14 | 15 | /* 16 | * make_tree: 17 | * Used to construct the segment tree. It uses the baseArray for construction 18 | */ 19 | void make_tree(int cur, int s, int e) { 20 | if(s == e-1) { 21 | st[cur] = baseArray[s]; 22 | return; 23 | } 24 | int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; 25 | make_tree(c1, s, m); 26 | make_tree(c2, m, e); 27 | st[cur] = st[c1] > st[c2] ? st[c1] : st[c2]; 28 | } 29 | 30 | /* 31 | * update_tree: 32 | * Point update. Update a single element of the segment tree. 33 | */ 34 | void update_tree(int cur, int s, int e, int x, int val) { 35 | if(s > x || e <= x) return; 36 | if(s == x && s == e-1) { 37 | st[cur] = val; 38 | return; 39 | } 40 | int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; 41 | update_tree(c1, s, m, x, val); 42 | update_tree(c2, m, e, x, val); 43 | st[cur] = st[c1] > st[c2] ? st[c1] : st[c2]; 44 | } 45 | 46 | /* 47 | * query_tree: 48 | * Given S and E, it will return the maximum value in the range [S,E) 49 | */ 50 | void query_tree(int cur, int s, int e, int S, int E) { 51 | if(s >= E || e <= S) { 52 | qt[cur] = -1; 53 | return; 54 | } 55 | if(s >= S && e <= E) { 56 | qt[cur] = st[cur]; 57 | return; 58 | } 59 | int c1 = (cur<<1), c2 = c1 | 1, m = (s+e)>>1; 60 | query_tree(c1, s, m, S, E); 61 | query_tree(c2, m, e, S, E); 62 | qt[cur] = qt[c1] > qt[c2] ? qt[c1] : qt[c2]; 63 | } 64 | 65 | /* 66 | * query_up: 67 | * It takes two nodes u and v, condition is that v is an ancestor of u 68 | * We query the chain in which u is present till chain head, then move to next chain up 69 | * We do that way till u and v are in the same chain, we query for that part of chain and break 70 | */ 71 | 72 | int query_up(int u, int v) { 73 | if(u == v) return 0; // Trivial 74 | int uchain, vchain = chainInd[v], ans = -1; 75 | // uchain and vchain are chain numbers of u and v 76 | while(1) { 77 | uchain = chainInd[u]; 78 | if(uchain == vchain) { 79 | // Both u and v are in the same chain, so we need to query from u to v, update answer and break. 80 | // We break because we came from u up till v, we are done 81 | if(u==v) break; 82 | query_tree(1, 0, ptr, posInBase[v]+1, posInBase[u]+1); 83 | // Above is call to segment tree query function 84 | if(qt[1] > ans) ans = qt[1]; // Update answer 85 | break; 86 | } 87 | query_tree(1, 0, ptr, posInBase[chainHead[uchain]], posInBase[u]+1); 88 | // Above is call to segment tree query function. We do from chainHead of u till u. That is the whole chain from 89 | // start till head. We then update the answer 90 | if(qt[1] > ans) ans = qt[1]; 91 | u = chainHead[uchain]; // move u to u's chainHead 92 | u = pa[0][u]; //Then move to its parent, that means we changed chains 93 | } 94 | return ans; 95 | } 96 | 97 | /* 98 | * LCA: 99 | * Takes two nodes u, v and returns Lowest Common Ancestor of u, v 100 | */ 101 | int LCA(int u, int v) { 102 | if(depth[u] < depth[v]) swap(u,v); 103 | int diff = depth[u] - depth[v]; 104 | for(int i=0; i>i)&1 ) u = pa[i][u]; 105 | if(u == v) return u; 106 | for(int i=LN-1; i>=0; i--) if(pa[i][u] != pa[i][v]) { 107 | u = pa[i][u]; 108 | v = pa[i][v]; 109 | } 110 | return pa[0][u]; 111 | } 112 | 113 | void query(int u, int v) { 114 | /* 115 | * We have a query from u to v, we break it into two queries, u to LCA(u,v) and LCA(u,v) to v 116 | */ 117 | int lca = LCA(u, v); 118 | int ans = query_up(u, lca); // One part of path 119 | int temp = query_up(v, lca); // another part of path 120 | if(temp > ans) ans = temp; // take the maximum of both paths 121 | printf("%d\n", ans); 122 | } 123 | 124 | /* 125 | * change: 126 | * We just need to find its position in segment tree and update it 127 | */ 128 | void change(int i, int val) { 129 | int u = otherEnd[i]; 130 | update_tree(1, 0, ptr, posInBase[u], val); 131 | } 132 | 133 | /* 134 | * Actual HL-Decomposition part 135 | * Initially all entries of chainHead[] are set to -1. 136 | * So when ever a new chain is started, chain head is correctly assigned. 137 | * As we add a new node to chain, we will note its position in the baseArray. 138 | * In the first for loop we find the child node which has maximum sub-tree size. 139 | * The following if condition is failed for leaf nodes. 140 | * When the if condition passes, we expand the chain to special child. 141 | * In the second for loop we recursively call the function on all normal nodes. 142 | * chainNo++ ensures that we are creating a new chain for each normal child. 143 | */ 144 | void HLD(int curNode, int cost, int prev) { 145 | if(chainHead[chainNo] == -1) { 146 | chainHead[chainNo] = curNode; // Assign chain head 147 | } 148 | chainInd[curNode] = chainNo; 149 | posInBase[curNode] = ptr; // Position of this node in baseArray which we will use in Segtree 150 | baseArray[ptr++] = cost; 151 | 152 | int sc = -1, ncost; 153 | // Loop to find special child 154 | for(int i=0; i