Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <map>
- #include <set>
- #include <queue>
- #include <algorithm>
- #include <string>
- #include <cmath>
- #include <cstdio>
- #include <iomanip>
- #include <fstream>
- #include <cassert>
- #include <cstring>
- #include <unordered_set>
- #include <unordered_map>
- #include <numeric>
- #include <ctime>
- #include <bitset>
- #include <complex>
- using namespace std;
- typedef long long ll;
- #ifdef DEBUG
- const int MAXN = 10;
- #else
- const int MAXN = 2e5;
- #endif
- const int MAXLOG = 18;
- int n;
- vector<int> g[MAXN];
- int sz[MAXN];
- int tin[MAXN];
- int par[MAXN];
- int rt[MAXN];
- int pre[MAXN][MAXLOG];
- int segtree[4 * MAXN];
- void upd(int v, int tl, int tr, int pos, int x) {
- if (tl == tr) {
- segtree[v] += x;
- return;
- }
- int tm = (tl + tr) >> 1;
- if (pos <= tm) {
- upd(2 * v, tl, tm, pos, x);
- }
- else {
- upd(2 * v + 1, tm + 1, tr, pos, x);
- }
- segtree[v] = max(segtree[2 * v], segtree[2 * v + 1]);
- }
- int get(int v, int tl, int tr, int l, int r) {
- if (tl > r || l > tr) {
- return -1;
- }
- if (l <= tl && tr <= r) {
- return segtree[v];
- }
- int tm = (tl + tr) / 2;
- return max(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm + 1, tr, l, r));
- }
- int timer = 0;
- void dfs(int v, int p = -1) {
- sz[v] = 1;
- int mx = -1;
- int pos = -1;
- for (auto to : g[v]) {
- pos++;
- if (to == p) {
- continue;
- }
- dfs(to, v);
- if (mx == -1 || sz[to] > sz[g[v][mx]]) {
- mx = pos;
- }
- sz[v] += sz[to];
- }
- if (mx != -1) {
- swap(g[v][0], g[v][mx]);
- }
- }
- void calc(int v, int p = 0, int root = -1) {
- tin[v] = timer++;
- pre[v][0] = p;
- for (int i = 1; i < MAXLOG; i++) {
- pre[v][i] = pre[pre[v][i - 1]][i - 1];
- }
- if (root == -1) {
- root = v;
- }
- rt[v] = root;
- int alr = 0;
- for (auto to : g[v]) {
- if (to == p) {
- continue;
- }
- if (!alr) {
- calc(to, v, root);
- alr = 1;
- }
- else {
- calc(to, v);
- }
- }
- }
- int isp(int a, int b) {
- return tin[a] <= tin[b] && tin[b] <= tin[a] + sz[a] - 1;
- }
- int lca(int a, int b) {
- if (isp(a, b)) {
- return a;
- }
- if (isp(b, a)) {
- return b;
- }
- for (int i = MAXLOG - 1; i >= 0; i--) {
- if (!isp(pre[a][i], b)) {
- a = pre[a][i];
- }
- }
- return pre[a][0];
- }
- inline void init() {
- }
- inline void solve() {
- init();
- for (int i = 0; i < n - 1; i++) {
- int a, b;
- cin >> a >> b;
- a--, b--;
- g[a].push_back(b);
- g[b].push_back(a);
- }
- dfs(0);
- calc(0);
- // for (int i = 0; i < n; i++) {
- // cerr << tin[i] << ' ';
- // }
- // cerr << '\n';
- int m;
- cin >> m;
- for (int i = 0; i < m; i++) {
- char c;
- cin >> c;
- if (c == 'I') {
- int a, b;
- cin >> a >> b;
- a--;
- upd(1, 0, MAXN - 1, tin[a], b);
- }
- else {
- int l, r;
- cin >> l >> r;
- l--, r--;
- int w = lca(l, r);
- // cerr << l << ' ' << r << ' ' << w << '\n';
- int ans = 0;
- while (!isp(rt[l], w)) {
- // cerr << "get " << tin[rt[l]] << ' ' << tin[l] << '\n';
- ans = max(ans, get(1, 0, MAXN - 1, tin[rt[l]], tin[l]));
- l = pre[rt[l]][0];
- }
- // cerr << "get " << tin[w] << ' ' << tin[l] << '\n';
- ans = max(ans, get(1, 0, MAXN - 1, tin[w], tin[l]));
- while (!isp(rt[r], w)) {
- // cerr << "get " << tin[rt[r]] << ' ' << tin[r] << '\n';
- ans = max(ans, get(1, 0, MAXN - 1, tin[rt[r]], tin[r]));
- r = pre[rt[r]][0];
- }
- // cerr << "get " << tin[w] << ' ' << tin[r] << '\n';
- ans = max(ans, get(1, 0, MAXN - 1, tin[w], tin[r]));
- cout << ans << '\n';
- }
- }
- }
- signed main() {
- #ifdef DEBUG
- freopen("F.in", "r", stdin);
- freopen("F.out", "w", stdout);
- #else
- freopen("caves.in", "r", stdin);
- freopen("caves.out", "w", stdout);
- #endif
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- while (cin >> n)
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment