Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define int long long
- #define pb push_back
- #define pii pair<int,int>
- using namespace std;
- const int logn = 18, N = 1e5 + 10;
- vector<int> gr[N];
- int tin[N], tout[N], h[N], up[20][N], timer;
- void dfs(int v, int pr)
- {
- tin[v] = ++timer;
- up[0][v] = pr;
- for(int i = 1; i <= 19; i++)
- {
- up[i][v] = up[i - 1][up[i - 1][v]];
- }
- for(int to: gr[v])
- {
- if(to != pr)
- {
- h[to] = h[v] + 1;
- dfs(to, v);
- }
- }
- tout[v] = timer;
- }
- 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 = 19; i >= 0; i--)
- {
- if(!upper(up[i][a], b))
- {
- a = up[i][a];
- }
- }
- return up[0][a];
- }
- int len(int a, int b)
- {
- return h[a] + h[b] - 2 * h[lca(a, b)];
- }
- main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- int n, m;
- cin >> n;
- for(int i = 0; i < n - 1; i ++)
- {
- int l, r;
- cin >> l >> r;
- gr[l].pb(r);
- gr[r].pb(l);
- }
- dfs(1, 1);
- int q;
- cin >> q;
- //set
- auto cmp = [](int a, int b) {return tin[a] < tin[b];};
- set<int, decltype(cmp)> cur(cmp);
- //
- int ans = 0;
- while(q--) {
- int id;
- cin >> id;
- if(id == 1) {
- int v;
- cin >> v;
- cur.insert(v);
- auto it = cur.find(v);
- if(cur.size() != 1) {
- //already some vers in graph
- it++;
- if(it != cur.end()) {
- //v is not last
- int u = *it;
- int l = lca(v, u);
- if(l == 1) {
- //v got deeper
- it--;
- if(it == cur.begin()) {
- //v is new
- ans += (2 * len(1, v));
- } else {
- it--;
- u = *it;
- ans += (2 * len(v, lca(v, u)));
- }
- } else {
- if(l != v) {
- ans += (2 * len(v, l));
- }
- }
- } else {
- //v is last
- it--;
- it--;
- int l = lca(v, *it);
- ans += (2 * len(v, l));
- }
- } else {
- // no vers before
- ans += (2 * len(1, v));
- }
- }
- if(id == 2) {
- int v;
- cin >> v;
- if(cur.size() == 1) {
- //only one v
- cur.erase(v);
- ans = 0;
- } else {
- // more vs
- auto it = cur.find(v);
- it++;
- if(it == cur.end()) {
- //v is last
- it--;
- it--;
- int u = *it;
- int l = lca(u, v);
- ans -= (2 * len(l, v));
- cur.erase(v);
- } else {
- // v is not last
- int u = *it;
- int l = lca(u, v);
- if(l == 1) {
- // v and next are in diffrt subtrees
- it--;
- if(it == cur.begin()) {
- //v is 1 in subtree
- ans -= (2 * len(1, v));
- cur.erase(v);
- continue;
- }
- it--;
- u = *it;
- ans -= (2 * len(v, lca(v, u)));
- cur.erase(v);
- } else {
- //v and next are in one subtree
- if(l != v) {
- ans -= (2 * len(v, l));
- cur.erase(v);
- } else {
- cur.erase(v);
- }
- }
- }
- }
- }
- if(id == 3) {
- cout << ans << endl;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement