Advertisement
Guest User

600E.cpp

a guest
Jun 22nd, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.24 KB | None | 0 0
  1. /*
  2.     Solution: Euler tour + Mo algorithm, O(n sqrt(n))
  3. */
  4.  
  5. #include <iostream>
  6. #include <vector>
  7. #include <algorithm>
  8. #include <functional>
  9.  
  10. struct Query { // struct for query to segment of array from left = l to right = r
  11.     int l, r, id;
  12. };
  13.  
  14. typedef long long ll;
  15.  
  16. struct Statistic { // statistic on segment of array, can insert color, remove color, getting answer in O(1)
  17.    
  18.     std::vector<int> count; // count[color] - actual number of current color, where color from 1 to nColors
  19.    
  20.     std::vector<ll> sum;    // sum[count] - actual sum of unique colors for current number of colors
  21.    
  22.     Statistic(const int nColors) {
  23.         count.assign(nColors+1, 0);
  24.         sum.push_back(ll(nColors) * (nColors+1) / 2);
  25.     }
  26.    
  27.     void insert(const int color) {
  28.         auto& cnt = count[color];
  29.         sum[cnt] -= color;
  30.         ++cnt;
  31.         if (cnt >= (int)sum.size()) sum.push_back(0);
  32.         sum[cnt] += color;
  33.     }
  34.    
  35.     void remove(const int color) {
  36.         auto& cnt = count[color];
  37.         sum[cnt] -= color;
  38.         --cnt;
  39.         if ((int)sum.back() == 0) sum.pop_back();
  40.         sum[cnt] += color;
  41.     }
  42.    
  43.     ll answer() const {
  44.         return sum.back();
  45.     }
  46. };
  47.  
  48. int main() {
  49.     std::ios_base::sync_with_stdio(false);
  50.     std::cin.tie(0); std::cout.tie(0); std::cerr.tie(0);
  51.    
  52.     // Input colors of vertices, edges of tree:
  53.     int n;
  54.     std::cin >> n;
  55.    
  56.     std::vector<int> color(n);
  57.     for (auto& it : color) {
  58.         std::cin >> it;
  59.     }
  60.    
  61.     std::vector<std::vector<int>> edges(n);
  62.     for (int i = 1; i < n; ++i) {
  63.         int a, b;
  64.         std::cin >> a >> b;
  65.         --a, --b;
  66.         edges[a].push_back(b);
  67.         edges[b].push_back(a);
  68.     }
  69.    
  70.     // Euler tour on tree:
  71.    
  72.     std::vector<Query> queries;
  73.    
  74.     std::vector<int> arr;
  75.    
  76.     std::function<void(int,int)> visit = [&](const int curr, const int parent){
  77.         int left = (int)arr.size();
  78.         arr.push_back(color[curr]);
  79.         for (auto next : edges[curr]) {
  80.             if (next != parent) {
  81.                 visit(next, curr);
  82.             }
  83.         }
  84.         int right = (int)arr.size()-1;
  85.         queries.push_back(Query{left, right, curr});
  86.     };
  87.    
  88.     visit(0, -1);
  89.    
  90.     // Mo algorithm for queries offline:
  91.    
  92.     const int GSIZE = 256;
  93.    
  94.     std::sort(queries.begin(), queries.end(), [](const Query& a, const Query& b) {
  95.         if (a.l / GSIZE != b.l / GSIZE) {
  96.             return a.l < b.l;
  97.         }
  98.         return a.r < b.r;
  99.     });
  100.    
  101.     Statistic stat(n);
  102.    
  103.     std::vector<ll> answer(n);
  104.    
  105.     int left = 0, right = -1;
  106.    
  107.     for (const auto& q : queries) {
  108.         while (right < q.r) {
  109.             stat.insert(arr[right+1]);
  110.             ++right;
  111.         }
  112.         while (left < q.l) {
  113.             stat.remove(arr[left]);
  114.             ++left;
  115.         }
  116.         while (left > q.l) {
  117.             stat.insert(arr[left-1]);
  118.             --left;
  119.         }
  120.         while (right > q.r) {
  121.             stat.remove(arr[right]);
  122.             --right;
  123.         }
  124.         answer[q.id] = stat.answer();
  125.     }
  126.    
  127.     // Output:
  128.     for (auto& it : answer) {
  129.         std::cout << it << ' ';
  130.     }
  131.    
  132.     return 0;
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement