Advertisement
K_Y_M_bl_C

Untitled

Dec 20th, 2017
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.74 KB | None | 0 0
  1. #ifdef _DEBUG
  2. #define _GLIBCXX_DEBUG
  3. #endif
  4. #define _CRT_SECURE_NO_WARNINGS
  5. #include <bits/stdc++.h>
  6.    
  7. using namespace std;
  8.    
  9. typedef long long ll;
  10. typedef vector<ll> vll;
  11. typedef pair<int, int> pii;
  12. typedef vector<int> vi;
  13. typedef long double ld;
  14.    
  15. #define mk make_pair
  16. #define inb push_back
  17. #define enb emplace_back
  18. #define X first
  19. #define Y second
  20. #define all(v) v.begin(), v.end()
  21. #define sqr(x) (x) * (x)
  22. #define TIME 1.0 * clock() / CLOCKS_PER_SEC
  23. #define y1 AYDARBOG
  24. //continue break pop_back return
  25.    
  26. int solve();
  27.    
  28. int main()
  29. {
  30.     //ios_base::sync_with_stdio(0);
  31.     //cin.tie(0);
  32. #define TASK "mail"
  33. #ifndef _DEBUG
  34.     //freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
  35. #endif
  36.     solve();
  37. #ifdef _DEBUG
  38.     fprintf(stderr, "\nTIME: %.3f\n", TIME);
  39. #endif
  40. }
  41.    
  42. const int BUFSZ = (int)1e6 + 7;
  43. char buf[BUFSZ];
  44. string get_str()
  45. {
  46.     scanf(" %s", buf);
  47.     return string(buf);
  48. }
  49.  
  50. int solve()
  51. {
  52.     int n, q;
  53.     scanf("%d %d", &n, &q);
  54.     vector<vi> g(n);
  55.     for (int i = 0; i < n - 1; ++i)
  56.     {
  57.         int x, y;
  58.         scanf("%d %d", &x, &y);
  59.         --x, --y;
  60.         g[x].inb(y);
  61.         g[y].inb(x);
  62.     }
  63.  
  64. // LCA BEGIN
  65.  
  66.     vi lh(n);
  67.     vector<vi> up(18, vi(n));
  68.     function<void(int)> ldfs = [&](int u)
  69.     {
  70.         for (int to : g[u])
  71.         {
  72.             if (up[0][u] == to)
  73.                 continue;
  74.             up[0][to] = u;
  75.             lh[to] = lh[u] + 1;
  76.             ldfs(to);
  77.         }
  78.     };
  79.     ldfs(0);
  80.     for (int l = 1; l < 18; ++l)
  81.     {
  82.         for (int i = 0; i < n; ++i)
  83.         {
  84.             up[l][i] = up[l - 1][up[l - 1][i]];
  85.         }
  86.     }
  87.     auto getdst = [&](int x, int y)
  88.     {
  89.         int a = x, b = y;
  90.         if (lh[a] < lh[b])
  91.             swap(a, b);
  92.         int dst = lh[a] - lh[b];
  93.         for (int l = 17; l >= 0; --l)
  94.         {
  95.             if ((dst >> l) & 1)
  96.                 a = up[l][a];
  97.         }
  98.         int lca = a;
  99.         if (a != b)
  100.         {
  101.             for (int l = 17; l >= 0; --l)
  102.             {
  103.                 if (up[l][a] != up[l][b])
  104.                     a = up[l][a], b = up[l][b];
  105.             }
  106.             lca = up[0][a];
  107.         }
  108.         return lh[x] + lh[y] - 2 * lh[lca];
  109.     };
  110.  
  111. // LCA END
  112.  
  113. // BUILD CD BEGIN
  114.  
  115.     vi h(n, -1), p(n, -1);
  116.     function<int(int, int, int&, int)> dfs = [&](int u, int sz, int &cur, int pr)
  117.     {
  118.         int sum = 1;
  119.         for (int to : g[u])
  120.         {
  121.             if (to == pr || h[to] != -1)
  122.                 continue;
  123.             sum += dfs(to, sz, cur, u);
  124.         }
  125.         if (cur == -1)
  126.         {
  127.             if (2 * sum >= sz || pr == -1)
  128.                 cur = u;
  129.         }
  130.         return sum;
  131.     };
  132.     vector<vector<pii>> pos(n); //position
  133.     vector<vll> sumdst(2, vll(n)); //sum distance 4 each col
  134.     vector<vi> sumcnt(2, vi(n)); //sum cnt
  135.     vi col(n); //cvet
  136.     vector<vector<vll>> csd(n, vector<vll>(2)); //cmp sumdst
  137.     vector<vector<vi>> cntv(n, vector<vi>(2)); //cnt v cmp
  138.     function<void(int, int, int, int, int)> calc = [&](int u, int center, int id, int r, int pp)
  139.     {
  140.         pos[u].inb(mk(center, id));
  141.         //printf("u : %d dst : %d\n", u + 1, r);
  142.         csd[center][0][id] += r;
  143.         ++cntv[center][0][id];
  144.         for (int to : g[u])
  145.         {
  146.             if (to == pp || h[to] != -1)
  147.                 continue;
  148.             calc(to, center, id, r + 1, u);
  149.         }
  150.     };
  151.     function<void(int, int, int, int)> build = [&](int u, int sz, int ch, int lst)
  152.     {
  153.         int cur = -1, kek;
  154.         int csz = dfs(u, sz, kek, -1);
  155.         dfs(u, csz, cur, -1);
  156.         //printf("NEW CENTER AND SIZE: %d %d\n", cur + 1, csz);
  157.         h[cur] = ch;
  158.         p[cur] = lst;
  159.         for (int i = 0; i < 2; ++i)
  160.         {
  161.             csd[cur][i].resize((int)g[cur].size());
  162.             cntv[cur][i].resize((int)g[cur].size());
  163.         }
  164.         int it = 0;
  165.         sumcnt[0][cur] = 1;
  166.         for (int to : g[cur])
  167.         {
  168.             if (h[to] != -1)
  169.                 continue;
  170.             calc(to, cur, it, 1, cur);
  171.             //printf("GOT AWAY FROM : %d %lld %d\n", to + 1, csd[cur][0][it], cntv[cur][0][it]);
  172.             sumdst[0][cur] += csd[cur][0][it];
  173.             sumcnt[0][cur] += cntv[cur][0][it];
  174.             ++it;
  175.         }
  176.         //printf("%lld %d\n", sumdst[0][cur], sumcnt[0][cur]);
  177.         for (int to : g[cur])
  178.         {
  179.             if (h[to] != -1)
  180.                 continue;
  181.             build(to, sz / 2, ch + 1, cur);
  182.         }
  183.     };
  184.     build(0, n, 0, -1);
  185.  
  186. // BUILD CD END
  187.  
  188.     while (q--)
  189.     {
  190.         int cmd;
  191.         scanf("%d", &cmd);
  192.         --cmd;
  193.         int u;
  194.         scanf("%d", &u);
  195.         --u;
  196.         if (cmd)
  197.         {
  198.             //getans
  199.             int cc = col[u];
  200.             ll ans = sumdst[cc][u];
  201.             for (auto &cur : pos[u])
  202.             {
  203.                 int center = cur.X;
  204.                 int id = cur.Y;
  205.                 ll cv = sumcnt[cc][center] - cntv[center][cc][id];
  206.                 ll cd = sumdst[cc][center] - csd[center][cc][id];
  207.                 ans += cv * getdst(center, u) + cd;
  208.             }
  209.             printf("%lld\n", ans);
  210.         }
  211.         else
  212.         {
  213.             //update
  214.             --sumcnt[col[u]][u];
  215.             col[u] ^= 1;
  216.             int cc = col[u];
  217.             ++sumcnt[col[u]][u];
  218.             for (auto &cur : pos[u])
  219.             {
  220.                 int center = cur.X;
  221.                 int id = cur.Y;
  222.                 --sumcnt[cc ^ 1][center];
  223.                 ++sumcnt[cc][center];
  224.                 --cntv[center][cc ^ 1][id];
  225.                 ++cntv[center][cc][id];
  226.                 int dd = getdst(center, u);
  227.                 //printf("DAMN DISTANCE: %d %d %d\n", center + 1, u + 1, dd);
  228.                 sumdst[cc ^ 1][center] -= dd;
  229.                 sumdst[cc][center] += dd;
  230.                 csd[center][cc ^ 1][id] -= dd;
  231.                 csd[center][cc][id] += dd;
  232.             }
  233.         }
  234.     }
  235.     return 0;
  236. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement