Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct SegmentTree
- {
- vector<pair<ll, ll>> t;
- SegmentTree() {};
- SegmentTree(int n) { t.resize(4 * n); };
- int size()
- {
- return (int)t.size() / 4;
- }
- void push(int v, int tl, int tr)
- {
- if (!t[v].Y)
- return;
- t[v].X += t[v].Y * (tr - tl + 1);
- if (tl != tr)
- t[2 * v + 1].Y += t[v].Y, t[2 * v + 2].Y += t[v].Y;
- t[v].Y = 0;
- }
- void update(int v, int tl, int tr, int l, int r)
- {
- push(v, tl, tr);
- if (l > tr || tl > r)
- return;
- if (l <= tl && tr <= r)
- {
- t[v].Y++;
- push(v, tl, tr);
- return;
- }
- int tm = tl + tr >> 1;
- update(2 * v + 1, tl, tm, l, r);
- update(2 * v + 2, tm + 1, tr, l, r);
- t[v].X = t[2 * v + 1].X + t[2 * v + 2].X;
- }
- ll get(int v, int tl, int tr, int l, int r)
- {
- push(v, tl, tr);
- if (l > tr || tl > r)
- return 0;
- if (l <= tl && tr <= r)
- return t[v].X;
- int tm = tl + tr >> 1;
- return get(2 * v + 1, tl, tm, l, r) + get(2 * v + 2, tm + 1, tr, l, r);
- }
- };
- int solve()
- {
- int n, q;
- scanf("%d %d", &n, &q);
- int ok = (n <= 6);
- vector<vi> g(n);
- for (int i = 0; i < n - 1; ++i)
- {
- int x, y;
- scanf("%d %d", &x, &y);
- --x, --y;
- g[x].inb(y);
- g[y].inb(x);
- }
- vi post(n), idt(n, -1);
- vector<SegmentTree> T;
- vi sz(n);
- vi headt;
- vi nxt(n, -1);
- vector<vi> up(17, vi(n));
- vi h(n);
- vi ph(n);
- function<void(int, int)> dfs = [&](int u, int pr)
- {
- up[0][u] = pr;
- sz[u] = 1;
- for (int to : g[u])
- {
- if (to == pr)
- continue;
- h[to] = h[u] + 1;
- dfs(to, u);
- sz[u] += sz[to];
- }
- for (int to : g[u])
- {
- if (to == pr)
- continue;
- if (sz[to] * 2 >= sz[u])
- nxt[u] = to, ph[to] = 1;
- }
- };
- dfs(0, 0);
- for (int l = 1; l < 17; ++l)
- {
- for (int i = 0; i < n; ++i)
- {
- up[l][i] = up[l - 1][up[l - 1][i]];
- }
- }
- auto getlca = [&](int x, int y)
- {
- if (h[x] < h[y])
- swap(x, y);
- int dst = h[x] - h[y];
- for (int l = 16; l >= 0; --l)
- {
- if ((dst >> l) & 1)
- x = up[l][x];
- }
- if (x == y)
- return x;
- for (int l = 16; l >= 0; --l)
- {
- if (up[l][x] != up[l][y])
- x = up[l][x], y = up[l][y];
- }
- return up[0][x];
- };
- vi was(n);
- for (int i = 0; i < n; ++i)
- {
- if (nxt[i] == -1 || was[i])
- continue;
- int u = i;
- int cid = T.size();
- headt.inb(u);
- int csz = 0;
- while (u != -1)
- {
- was[u] = 1;
- post[u] = csz;
- idt[u] = cid;
- csz++;
- u = nxt[u];
- }
- T.inb(SegmentTree(csz));
- }
- vi cst(n);
- auto get = [&](int x, int y)
- {
- int u = x;
- ll ans = 0;
- while (h[u] > h[y])
- {
- if (idt[u] == -1 || !ph[u])
- {
- ans += cst[u];
- u = up[0][u];
- continue;
- }
- if (idt[u] == idt[y])
- {
- ans += T[idt[u]].get(0, 0, T[idt[u]].size() - 1, post[y], post[u] - 1);
- u = y;
- }
- else
- {
- ans += T[idt[u]].get(0, 0, T[idt[u]].size() - 1, 0, post[u] - 1);
- u = headt[idt[u]];
- }
- }
- return ans;
- };
- auto update = [&](int x, int y)
- {
- int u = x;
- while (h[u] > h[y])
- {
- if (idt[u] == -1 || !ph[u])
- {
- cst[u]++;
- u = up[0][u];
- continue;
- }
- if (idt[u] == idt[y])
- {
- T[idt[u]].update(0, 0, T[idt[u]].size() - 1, post[y], post[u] - 1);
- u = y;
- }
- else
- {
- T[idt[u]].update(0, 0, T[idt[u]].size() - 1, 0, post[u] - 1);
- u = headt[idt[u]];
- }
- }
- };
- while (q--)
- {
- char cmd;
- scanf(" %c", &cmd);
- int x, y;
- scanf("%d %d", &x, &y);
- --x, --y;
- int lca = getlca(x, y);
- if (cmd == 'P')
- {
- update(x, lca);
- update(y, lca);
- }
- else
- {
- printf("%lld\n", get(x, lca) + get(y, lca));
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement