Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma comment(linker, "/STACK:32000000")
- #include <iostream>
- #include <cstdio>
- #include <vector>
- using namespace std;
- vector <vector <int> > g, lca_arr, decomp, t;
- vector <int> anc, sz, tin, tout, heavy, top, val;
- vector <pair <int, int> > pos;
- int n, l, timer;
- bool is_heavy(int v, int to)
- {
- if (sz[to] * 2 >= sz[v])
- return true;
- return false;
- }
- void dfs(int v, int pr = 0)
- {
- anc[v] = pr;
- tin[v] = timer++;
- sz[v] = 1;
- lca_arr[v][0] = pr;
- for (int i = 1; i <= l; i++)
- lca_arr[v][i] = lca_arr[lca_arr[v][i - 1]][i - 1];
- for (size_t i = 0; i < g[v].size(); i++)
- if (pr != g[v][i])
- {
- dfs(g[v][i], v);
- sz[v] += sz[g[v][i]];
- }
- for (size_t i = 0; i < g[v].size(); i++)
- if (g[v][i] != pr && is_heavy(v, g[v][i]))
- heavy[v] = g[v][i];
- tout[v] = timer++;
- }
- void init()
- {
- while ((1 << l) <= n)
- l++;
- lca_arr.assign(n, vector <int> (l + 1));
- g.resize(n);
- anc.resize(n);
- sz.resize(n);
- tin.resize(n);
- tout.resize(n);
- heavy.resize(n, -1);
- pos.resize(n);
- val.resize(n);
- timer = 0;
- }
- void build_hld()
- {
- for (int i = 0; i < n; i++)
- {
- if (heavy[i] == -1)
- {
- int v = i;
- decomp.resize(decomp.size() + 1);
- top.resize(top.size() + 1);
- decomp.back().push_back(v);
- int f = decomp.size() - 1;
- int s = 0;
- pos[v] = make_pair(f, s++);
- if (is_heavy(anc[v], v))
- {
- v = anc[v];
- while (true)
- {
- decomp.back().push_back(v);
- pos[v] = make_pair(f, s++);
- if (v == 0 || !is_heavy(anc[v], v))
- break;
- v = anc[v];
- }
- top.back() = anc[v];
- }
- }
- }
- t.resize(decomp.size());
- for (int i = 0; i < (int)decomp.size(); i++)
- t[i].resize(decomp[i].size() * 4);
- }
- void upd(int v, int l, int r, int ind, int pos)
- {
- //cout << l << ' ' << r << ' ' << v << ' ' << pos << ' ' << endl;
- if (l > r)
- return;
- if (pos < l || pos > r)
- return;
- if (l == r)
- {
- if (l == pos)
- t[ind][v] = val[decomp[ind][pos]];
- return;
- }
- int m = (l + r) >> 1;
- upd(v << 1, l, m, ind, pos);
- upd((v << 1) + 1, m + 1, r, ind, pos);
- t[ind][v] = max(t[ind][v << 1], t[ind][(v << 1) + 1]);
- }
- int query(int v, int l, int r, int t_l, int t_r, int ind)
- {
- //cout << l << ' ' << r << endl;
- if (l > r)
- return 0;
- if (l == r && l >= t_l && l <= t_r)
- return t[ind][v];
- if (l >= t_l && r <= t_r)
- return t[ind][v];
- if (l > t_r || r < t_l)
- return 0;
- int m = (l + r) >> 1;
- int ans = query(v << 1, l, m, t_l, t_r, ind);
- ans = max(ans, query((v << 1) + 1, m + 1, r, t_l, t_r, ind));
- return ans;
- }
- bool upper(int a, int b)
- {
- return (tin[a] <= tin[b] && tout[a] >= tout[b]);
- }
- int lca(int a, int b)
- {
- if (upper(a, b))
- return a;
- if (upper(b, a))
- return b;
- for (int i = l; i >= 0; i--)
- if (!upper(lca_arr[a][i], b))
- a = lca_arr[a][i];
- return lca_arr[a][0];
- }
- int f(int a, int q)
- {
- int ans1 = 0;
- //cout << a + 1 << ' ' << q + 1 << endl;
- if (pos[a].first == pos[q].first)
- {
- ans1 = query(1, 0, decomp[pos[a].first].size() - 1, min(pos[a].second, pos[q].second), max(pos[a].second, pos[q].second), pos[a].first);
- }
- else
- {
- ans1 = query(1, 0, decomp[pos[a].first].size() - 1, pos[a].second, decomp[pos[a].first].size() - 1, pos[a].first);
- a = top[pos[a].first];
- //cout << a << endl;
- while (a != 0 && pos[a].first != pos[q].first)
- {
- ans1 = max(ans1, t[pos[a].first][1]);
- a = top[pos[a].first];
- }
- ans1 = max(ans1, query(1, 0, decomp[pos[q].first].size() - 1, 0, pos[q].second, pos[q].first));
- }
- return ans1;
- }
- int get_ans(int a, int b)
- {
- if (pos[a].first == pos[b].first)
- {
- return query(1, 0, decomp[pos[a].first].size() - 1, min(pos[b].second, pos[a].second), max(pos[b].second, pos[a].second), pos[a].first);
- }
- int q = lca(a, b);
- return max(f(a, q), f(b, q));
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in", "r", stdin);
- #endif
- cin >> n;
- init();
- int a, b;
- for (int i = 0; i < n - 1; i++)
- {
- cin >> a >> b;
- a--, b--;
- g[a].push_back(b);
- g[b].push_back(a);
- }
- dfs(0);
- build_hld();
- /*for (int i = 0; i < (int)decomp.size(); i++)
- {
- for (int j = 0; j < (int)decomp[i].size(); j++)
- cout << decomp[i][j] << ' ';
- cout << endl;
- }*/
- char c;
- int m;
- cin >> m;
- for (int i = 0; i < m; i++)
- {
- cin >> c >> a >> b;
- if (c == 'I')
- {
- a--;
- val[a] += b;
- upd(1, 0, decomp[pos[a].first].size() - 1, pos[a].first, pos[a].second);
- }
- else
- {
- a--, b--;
- cout << get_ans(a, b) << endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment