Advertisement
K_Y_M_bl_C

Untitled

Dec 17th, 2017
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.35 KB | None | 0 0
  1. struct SegmentTree
  2. {
  3.     vector<pair<ll, ll>> t;
  4.     SegmentTree() {};
  5.     SegmentTree(int n) { t.resize(4 * n); };
  6.     int size()
  7.     {
  8.         return (int)t.size() / 4;
  9.     }
  10.     void push(int v, int tl, int tr)
  11.     {
  12.         if (!t[v].Y)
  13.             return;
  14.         t[v].X += t[v].Y * (tr - tl + 1);
  15.         if (tl != tr)
  16.             t[2 * v + 1].Y += t[v].Y, t[2 * v + 2].Y += t[v].Y;
  17.         t[v].Y = 0;
  18.     }
  19.     void update(int v, int tl, int tr, int l, int r)
  20.     {
  21.         push(v, tl, tr);
  22.         if (l > tr || tl > r)
  23.             return;
  24.         if (l <= tl && tr <= r)
  25.         {
  26.             t[v].Y++;
  27.             push(v, tl, tr);
  28.             return;
  29.         }
  30.         int tm = tl + tr >> 1;
  31.         update(2 * v + 1, tl, tm, l, r);
  32.         update(2 * v + 2, tm + 1, tr, l, r);
  33.         t[v].X = t[2 * v + 1].X + t[2 * v + 2].X;
  34.     }
  35.     ll get(int v, int tl, int tr, int l, int r)
  36.     {
  37.         push(v, tl, tr);
  38.         if (l > tr || tl > r)
  39.             return 0;
  40.         if (l <= tl && tr <= r)
  41.             return t[v].X;
  42.         int tm = tl + tr >> 1;
  43.         return get(2 * v + 1, tl, tm, l, r) + get(2 * v + 2, tm + 1, tr, l, r);
  44.     }
  45. };
  46.  
  47. int solve()
  48. {
  49.     int n, q;
  50.     scanf("%d %d", &n, &q);
  51.     int ok = (n <= 6);
  52.     vector<vi> g(n);
  53.     for (int i = 0; i < n - 1; ++i)
  54.     {
  55.         int x, y;
  56.         scanf("%d %d", &x, &y);
  57.         --x, --y;
  58.         g[x].inb(y);
  59.         g[y].inb(x);
  60.     }
  61.     vi post(n), idt(n, -1);
  62.     vector<SegmentTree> T;
  63.     vi sz(n);
  64.     vi headt;
  65.     vi nxt(n, -1);
  66.     vector<vi> up(17, vi(n));
  67.     vi h(n);
  68.     vi ph(n);
  69.     function<void(int, int)> dfs = [&](int u, int pr)
  70.     {
  71.         up[0][u] = pr;
  72.         sz[u] = 1;
  73.         for (int to : g[u])
  74.         {
  75.             if (to == pr)
  76.                 continue;
  77.             h[to] = h[u] + 1;
  78.             dfs(to, u);
  79.             sz[u] += sz[to];
  80.         }
  81.         for (int to : g[u])
  82.         {
  83.             if (to == pr)
  84.                 continue;
  85.             if (sz[to] * 2 >= sz[u])
  86.                 nxt[u] = to, ph[to] = 1;
  87.         }
  88.     };
  89.     dfs(0, 0);
  90.     for (int l = 1; l < 17; ++l)
  91.     {
  92.         for (int i = 0; i < n; ++i)
  93.         {
  94.             up[l][i] = up[l - 1][up[l - 1][i]];
  95.         }
  96.     }
  97.     auto getlca = [&](int x, int y)
  98.     {
  99.         if (h[x] < h[y])
  100.             swap(x, y);
  101.         int dst = h[x] - h[y];
  102.         for (int l = 16; l >= 0; --l)
  103.         {
  104.             if ((dst >> l) & 1)
  105.                 x = up[l][x];
  106.         }
  107.         if (x == y)
  108.             return x;
  109.         for (int l = 16; l >= 0; --l)
  110.         {
  111.             if (up[l][x] != up[l][y])
  112.                 x = up[l][x], y = up[l][y];
  113.         }
  114.         return up[0][x];
  115.     };
  116.     vi was(n);
  117.     for (int i = 0; i < n; ++i)
  118.     {
  119.         if (nxt[i] == -1 || was[i])
  120.             continue;
  121.         int u = i;
  122.         int cid = T.size();
  123.         headt.inb(u);
  124.         int csz = 0;
  125.         while (u != -1)
  126.         {
  127.             was[u] = 1;
  128.             post[u] = csz;
  129.             idt[u] = cid;
  130.             csz++;
  131.             u = nxt[u];
  132.         }
  133.         T.inb(SegmentTree(csz));
  134.     }
  135.     vi cst(n);
  136.     auto get = [&](int x, int y)
  137.     {
  138.         int u = x;
  139.         ll ans = 0;
  140.         while (h[u] > h[y])
  141.         {
  142.             if (idt[u] == -1 || !ph[u])
  143.             {
  144.                 ans += cst[u];
  145.                 u = up[0][u];
  146.                 continue;
  147.             }
  148.             if (idt[u] == idt[y])
  149.             {
  150.                 ans += T[idt[u]].get(0, 0, T[idt[u]].size() - 1, post[y], post[u] - 1);
  151.                 u = y;
  152.             }
  153.             else
  154.             {
  155.                 ans += T[idt[u]].get(0, 0, T[idt[u]].size() - 1, 0, post[u] - 1);
  156.                 u = headt[idt[u]];
  157.             }
  158.         }
  159.         return ans;
  160.     };
  161.     auto update = [&](int x, int y)
  162.     {
  163.         int u = x;
  164.         while (h[u] > h[y])
  165.         {
  166.             if (idt[u] == -1 || !ph[u])
  167.             {
  168.                 cst[u]++;
  169.                 u = up[0][u];
  170.                 continue;
  171.             }
  172.             if (idt[u] == idt[y])
  173.             {
  174.                 T[idt[u]].update(0, 0, T[idt[u]].size() - 1, post[y], post[u] - 1);
  175.                 u = y;
  176.             }
  177.             else
  178.             {
  179.                 T[idt[u]].update(0, 0, T[idt[u]].size() - 1, 0, post[u] - 1);
  180.                 u = headt[idt[u]];
  181.             }
  182.         }
  183.     };
  184.     while (q--)
  185.     {
  186.         char cmd;
  187.         scanf(" %c", &cmd);
  188.         int x, y;
  189.         scanf("%d %d", &x, &y);
  190.         --x, --y;
  191.         int lca = getlca(x, y);
  192.         if (cmd == 'P')
  193.         {
  194.             update(x, lca);
  195.             update(y, lca);
  196.         }
  197.         else
  198.         {
  199.             printf("%lld\n", get(x, lca) + get(y, lca));
  200.         }  
  201.     }
  202.     return 0;
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement