Advertisement
Guest User

Untitled

a guest
Nov 18th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.06 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2.  
  3. #include <stdio.h>
  4. #include <cstdio>
  5. #include <cstdlib>
  6. #include <iostream>
  7. #include <sstream>
  8. #include <string>
  9. #include <unordered_map>
  10. #include <unordered_set>
  11. //#include <windows.h>
  12. #include <math.h>
  13. #include <algorithm>
  14. #include <bitset>
  15. #include <cassert>
  16. #include <climits>
  17. #include <ctime>
  18. #include <fstream>
  19. #include <functional>
  20. #include <iomanip>
  21. #include <locale>
  22. #include <map>
  23. #include <queue>
  24. #include <random>
  25. #include <set>
  26. #include <stack>
  27. #include <vector>
  28.  
  29. using namespace std;
  30.  
  31. #define forn(i, n) for (int i = 0; i < n; i++)
  32. #define what_is(x) cerr << '\n' << #x << " = " << x << '\n'
  33. #define print_arr(heh) cerr << '\n'; for (auto u : heh) cerr << u << ' '; cerr << '\n'
  34. #define print_arri(heh) cerr << '\n'; for (int i = 0; i < heh.size(); i++) cerr << #heh << "[" << i << "] = " << heh[i] << '\n'
  35. //#define endl '\n'
  36. #define all(a) a.begin(), a.end()
  37. //#define int long long
  38. #define ll long long
  39. #define ld long double
  40. #define DEBUG
  41.  
  42. struct edge {
  43.     int num;
  44.     int distance;
  45.     int ans;
  46.  
  47.     edge() {
  48.  
  49.     }
  50.  
  51.     edge(const int num, const int distance) : num(num), distance(distance) {
  52.  
  53.     }
  54.  
  55.     bool operator<(const edge& b) {
  56.         return distance < b.distance;
  57.     }
  58. };
  59.  
  60. vector <vector <int>> g;
  61. vector <int> block;
  62. vector <int> treeSize;
  63. vector <int> centrPar;
  64. vector <bool> color;
  65. vector <int> ansWhite;
  66. vector <int> ansBlack;
  67. vector <int> countWhite;
  68. vector <int> countBlack;
  69. vector <int> whiteContribution;
  70. vector <int> blackContribution;
  71.  
  72. vector <vector <edge>> centrEdges;
  73. vector <unordered_map<int, int>> distFromCentroid;
  74.  
  75. int n, m;
  76.  
  77. //dfs
  78. int calcSizes(int v, int p) {
  79.     treeSize[v] = 1;
  80.  
  81.     for (auto u : g[v]) {
  82.         if (u != p && !block[u])
  83.             treeSize[v] += calcSizes(u, v);
  84.     }
  85.     return treeSize[v];
  86. }
  87.  
  88. int findCentr(int v, int p, int n) {
  89.     for (auto u : g[v]) {
  90.         if (u != p && !block[u] &&  treeSize[u] * 2 > n) {
  91.             return findCentr(u, v, n);
  92.         }
  93.     }
  94.     return v;
  95. }
  96.  
  97. void calcDistFromCentroid(int v, int p, int dist, vector <edge>& edges) {
  98.     for (auto u : g[v]) {
  99.         if (u != p && !block[u]) {
  100.             edges.push_back(edge(u, dist + 1));
  101.  
  102.             calcDistFromCentroid(u, v, dist + 1, edges);
  103.         }
  104.     }
  105. }
  106.  
  107. int calcContribution(int v, int p, int dist) {
  108.     int curAns = dist;
  109.     for (auto u : g[v]) {
  110.         if (u != p && !block[u]) {
  111.             curAns += calcContribution(u, v, dist + 1);
  112.         }
  113.     }
  114.     return curAns;
  115. }
  116.  
  117. void buildCentr(int v, int p, int contr) {
  118.     int curSize = calcSizes(v, p);
  119.  
  120.     int centroid = findCentr(v, p, curSize);
  121.    
  122.     centrPar[centroid] = p;
  123.    
  124.  
  125.     centrEdges[centroid].push_back(edge(centroid, 0));
  126.     calcDistFromCentroid(centroid, -1, 0, centrEdges[centroid]);
  127.     sort(all(centrEdges[centroid]));
  128.     for (auto u : centrEdges[centroid]) {
  129.         distFromCentroid[centroid][u.num] = u.distance;
  130.         ansWhite[centroid] += u.distance;
  131.     }
  132.     countWhite[centroid] = centrEdges[centroid].size();
  133.  
  134.     whiteContribution[centroid] = contr;
  135.  
  136.     /*centrEdges[centroid][0].ans = centrEdges[centroid][0].num;
  137.     for (size_t i = 1; i < centrEdges[centroid].size(); i++) {
  138.         centrEdges[centroid][i].ans = min(centrEdges[centroid][i].num, centrEdges[centroid][i - 1].ans);
  139.     }*/
  140.    
  141.     block[centroid] = 1;
  142.  
  143.  
  144.     for (auto u : g[centroid]) {
  145.         if (u != p && !block[u]) {
  146.             int contr = calcContribution(u, -1, 1);
  147.             buildCentr(u, centroid, contr);
  148.         }
  149.     }
  150.  
  151. }
  152.  
  153. void updateColor(int v, int start) {
  154.     if (v == -1) return;
  155.  
  156.     if (color[start] == 0) {
  157.         ansWhite[v] += distFromCentroid[v][start];
  158.         ansBlack[v] -= distFromCentroid[v][start];
  159.         countWhite[v]++;
  160.         countBlack[v]--;
  161.         if (centrPar[v] != -1) {
  162.             whiteContribution[v] += distFromCentroid[centrPar[v]][start];
  163.             blackContribution[v] -= distFromCentroid[centrPar[v]][start];
  164.         }
  165.     }
  166.     else {
  167.         ansWhite[v] -= distFromCentroid[v][start];
  168.         ansBlack[v] += distFromCentroid[v][start];
  169.         countWhite[v]--;
  170.         countBlack[v]++;
  171.         if (centrPar[v] != -1) {
  172.             whiteContribution[v] -= distFromCentroid[centrPar[v]][start];
  173.             blackContribution[v] += distFromCentroid[centrPar[v]][start];
  174.         }
  175.     }
  176.  
  177.     updateColor(centrPar[v], start);
  178. }
  179.  
  180. ll getAns(int v, int p, int start) {
  181.     if (v == -1) return 0;
  182.     int d = distFromCentroid[v][start];
  183.  
  184.     if (color[start] == 0) {
  185.         ll curAns = ansWhite[v] + d * countWhite[v];
  186.         if (p != v) {
  187.             curAns -= (whiteContribution[p] + d * countWhite[p]);
  188.         }
  189.         return curAns + getAns(centrPar[v], v, start);
  190.     }
  191.     else {
  192.         ll curAns = ansBlack[v] + d * countBlack[v];
  193.         if (p != v) {
  194.             curAns -= (blackContribution[p] + d * countBlack[p]);
  195.         }
  196.         return curAns + getAns(centrPar[v], v, start);
  197.     }
  198. }
  199.  
  200. //#define TEST
  201.  
  202. #ifdef TEST
  203. #include "testB3.h"
  204. #endif
  205.  
  206. int32_t main() {
  207.     ios::sync_with_stdio(0);
  208.     cin.tie(0);
  209.     cin >> n >> m;
  210.  
  211.     g.resize(n);
  212.     block.resize(n);
  213.     treeSize.resize(n);
  214.     centrPar.resize(n);
  215.     centrEdges.resize(n);
  216.     distFromCentroid.resize(n);
  217.     color.resize(n);
  218.     ansBlack.resize(n);
  219.     ansWhite.resize(n);
  220.     countWhite.resize(n);
  221.     countBlack.resize(n);
  222.     whiteContribution.resize(n);
  223.     blackContribution.resize(n);
  224.  
  225.  
  226.     forn(i, n - 1) {
  227.         int a, b;
  228.         cin >> a >> b;
  229.         a--; b--;
  230.  
  231.         g[a].push_back(b);
  232.         g[b].push_back(a);
  233.     }
  234.     buildCentr(0, -1, 0);
  235.  
  236. #ifdef TEST
  237.     test();
  238. #endif
  239.  
  240.     forn(i, m) {
  241.         int t, v;
  242.         cin >> t >> v;
  243.         v--;
  244.         if (t == 1) {
  245.             color[v] = !color[v];
  246.             updateColor(v, v);
  247.         }
  248.         else {
  249.             cout << getAns(v, v, v) << '\n';
  250.         }
  251.  
  252.     }
  253.    
  254.  
  255. #ifdef DEBUG
  256.     cerr << "\nTime: " << (double)clock() / CLOCKS_PER_SEC << endl;
  257. #endif
  258.     return 0;
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement