Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /** By @ZhakudaMagzhan **/
- # include <bits/stdc++.h>
- # define fi first
- # define se second
- # define y1 ioi_ioi
- # define endl "\n"
- # define ioi exit(0)
- # define mp make_pair
- # define pp pop_back
- # define pb push_back
- # define ub upper_bound
- # define lb lower_bound
- # define sqr(x) (x)*(x)
- # define sz(x) (int)x.size()
- # define all(x) x.begin(), x.end()
- # define bit(x) __builtin_popcountll(x)
- # define uniq(x) x.resize(unique(all(x))-x.begin())
- # define CLOCK clock()/(double)CLOCKS_PER_SEC
- # define rep(i, a, n) for (int i = a; i <= n; ++i)
- # define per(i, a, n) for (int i = n; i >= a; --i)
- # define arep(i, a, n, x) for (int i = a; i <= n; i += x)
- # define aper(i, a, n, x) for (int i = n; i >= a; i -= x)
- using namespace std;
- typedef long double ld;
- typedef long long ll;
- typedef unsigned long long ull;
- typedef pair <ll, ll> pll;
- typedef pair <int,int> pii;
- typedef vector <ll> vll;
- typedef vector <int> vi;
- typedef vector <pii> vpii;
- const int inf = (int) 2e9, mod = 999983ll;
- const ll linf = (ll) 2e18;
- int kob (int x, int y) { return ((ll)x * y) % mod; }
- int aza (int x, int y) { x -= y; if (x < 0) return x + mod; return x; }
- int kos (int x, int y) { x += y; if (x >= mod) return x - mod; return x; }
- const int maxn = (int) 1e5 + 666, maxn2 = (int) 1e6 + 666;
- int n, a[maxn], T[maxn*4], b[maxn], top[maxn], lrpos[maxn];
- int cntCh[maxn]; // balalarin sanaimiz
- vector <int> g[maxn], ans; // graph
- vector <int> now;
- bool used[maxn];
- int comp = -1; /// hld-nin komponenttari
- vector <pii> lr; /// l-r lari saktaladi
- int pos[maxn]; ///
- /// LCA
- int tin[maxn], tout[maxn], timer;
- int up[maxn][25];
- void preDfs (int x, int pr = -1) {
- tin[x] = ++ timer;
- up[x][0] = pr;
- for (int i = 1; i <= 20; ++ i)
- up[x][i] = up[up[x][i-1]][i-1];
- if (sz (g[x]) == 1 && g[x][0] == pr) {
- cntCh[x] = 1;
- }
- for (auto to: g[x]) {
- if (to != pr) {
- preDfs (to, x);
- cntCh[x] += cntCh[to];
- }
- }
- cntCh[x] ++;
- tout[x] = ++ timer;
- }
- void buildDfs (int x, bool start, int pr = -1) {
- if (start) {
- used[x] = true;
- int l, r;
- if (comp != -1) {
- l = sz (ans)+1;
- }
- ans.insert (ans.end (), all (now));
- if (comp != -1) {
- r = sz (ans);
- }
- if (comp != -1) {
- lr.pb (mp (l, r));
- }
- now.clear ();
- comp ++;
- now.pb (x);
- int opt = -1;
- int mx = -inf;
- for (auto to: g[x]) {
- if (to != pr && cntCh[to] > mx && !used[to]) {
- mx = a[to];
- opt = to;
- }
- }
- if (opt == -1) {
- return;
- }
- buildDfs (opt, 0, x);
- for (auto to: g[x]) {
- if (to == pr || to == opt || used[to]) {
- continue;
- }
- buildDfs (to, 1, x);
- }
- }
- else {
- used[x] = true;
- now.pb (x);
- int opt = -1;
- int mx = -inf;
- for (auto to: g[x]) {
- if (to != pr && cntCh[to] > mx && !used[to]) {
- mx = a[to];
- opt = to;
- }
- }
- if (opt == -1) {
- return;
- }
- buildDfs (opt, 0, x);
- for (auto to: g[x]) {
- if (to == pr || to == opt || used[to]) {
- continue;
- }
- buildDfs (to, 1, x);
- }
- }
- }
- ///*******DO*begin******///
- void buildTree (int x, int tl, int tr) {
- if (tl == tr) {
- T[x] = a[b[tl]];
- }
- else {
- int mid = (tl + tr) / 2;
- buildTree (x * 2, tl, mid);
- buildTree (x * 2 + 1, mid + 1, tr);
- T[x] = max (T[x*2], T[x*2+1]);
- }
- }
- int getsum (int x, int tl, int tr, int l, int r) {
- if (tr < l || r < tl) return -inf;
- if (l <= tl && tr <= r) return T[x];
- int mid = (tl + tr) / 2;
- return max (getsum (x * 2, tl, mid, l, r), getsum (x * 2 + 1, mid + 1, tr, l, r));
- }
- void upd (int x, int tl, int tr, int pos, int val) {
- if (tl == tr) {
- T[x] += val;
- }
- else {
- int mid = (tl + tr) / 2;
- if (pos <= mid) {
- upd (x * 2, tl, mid, pos, val);
- }
- else {
- upd (x * 2 + 1, mid + 1, tr, pos, val);
- }
- T[x] = max (T[x * 2], T[x * 2 + 1]);
- }
- }
- ///*******DO*end******///
- void build () {
- preDfs (1, 1);
- buildDfs (1, 1);
- if (sz (now)) {
- int l, r;
- if (comp != -1) {
- l = sz (ans)+1;
- }
- ans.insert (ans.end (), all (now));
- if (comp != -1) {
- r = sz (ans);
- }
- if (comp != -1) {
- lr.pb (mp (l, r));
- }
- now.clear ();
- }
- for (int i = 0; i < sz (ans); ++ i) {
- b[i+1] = ans[i];
- }
- int id = 0, cnt = 1;
- for (int i = 1; i <= n; ++ i) {
- pos[b[i]] = i;
- if (lr[id].fi <= i && i <= lr[id].se) {
- lrpos[b[i]] = id;
- if (top[id] == -1)
- top[id] = i;
- }
- else {
- ++ id;
- lrpos[b[i]] = id;
- top[id] = i;
- }
- }
- buildTree (1, 1, n);
- }
- int isParent (int x, int y) {
- return tin[x] <= tin[y] && tout[x] >= tout[y];
- }
- int getLca (int x, int y) {
- if (isParent (x, y)) return x;
- if (isParent (x, y)) return y;
- for (int i = 20; i >= 0; -- i) {
- if (!isParent (up[x][i], y))
- x = up[x][i];
- }
- return up[x][0];
- }
- int GETANS (int a, int c) {
- int ans = -inf;
- while (lrpos[a] != lrpos[c]) {
- int l = top[lrpos[a]];
- int r = pos[a];
- ans = max (ans, getsum (1, 1, n, l, r));
- a = up[b[l]][0];
- }
- int l = pos[c];
- int r = pos[a];
- ans = max (ans, getsum (1, 1, n, l, r));
- return ans;
- }
- int getAns (int x, int y) {
- int c = getLca (x, y);
- return max (GETANS (x, c), GETANS (y, c));
- }
- void upd (int x, int val) {
- x = pos[x];
- upd (1, 1, n, x, val);
- }
- int32_t main () {
- #define FN ""
- #ifdef GOLD
- freopen (FN".in", "r", stdin);
- freopen (FN".out", "w", stdout);
- #endif
- ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
- memset (top, -1, sizeof (top));
- cin >> n;
- for (int i = 1; i < n; ++ i) {
- int u, v;
- cin >> u >> v;
- g[u].pb (v);
- g[v].pb (u);
- }
- build ();
- int q;
- cin >> q;
- for (int i = 1; i <= q; ++ i) {
- char t;
- int u, b;
- cin >> t >> u >> b;
- if (t == 'G') {
- cout << getAns (u, b) << endl;
- }
- else {
- upd (u, b);
- a[u] += b;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement