Advertisement
Mlxa

### DCP Offline O(n log² n)

May 7th, 2019
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.61 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define all(x) x.begin(), x.end()
  3. using namespace std;
  4. using ll = long long;
  5. using ld = long double;
  6.  
  7. const int N = 1e6 + 2;
  8.  
  9. struct DSU {
  10.     int p[N], s[N];
  11.     int *ptr[N], val[N], size;
  12.      
  13.     DSU() {
  14.         fill_n(s, N, 1);
  15.         iota(p, p + N, 0);
  16.         size = 0;
  17.     }
  18.      
  19.     void save(int &x) {
  20.         ptr[size] = &x;
  21.         val[size] = x;
  22.         ++size;
  23.     }
  24.      
  25.     int get(int x) {
  26.         while (p[x] != x) {
  27.             x = p[x];
  28.         }
  29.         return x;
  30.     }
  31.      
  32.     void merge(int x, int y) {
  33.         x = get(x);
  34.         y = get(y);
  35.         if (x == y) {
  36.             return;
  37.         }
  38.         if (s[x] > s[y]) {
  39.             swap(x, y);
  40.         }
  41.         save(p[x]);
  42.         save(s[y]);
  43.         p[x] = y;
  44.         s[y] += s[x];
  45.     }
  46.      
  47.     void back_to(int s) {
  48.         while (size > s) {
  49.             --size;
  50.             *ptr[size] = val[size];
  51.         }
  52.     }
  53. } dsu;
  54.  
  55. int a[N], b[N], edges = 0;
  56. vector<int> add[2 * N];
  57.  
  58. void add_edge(int v, int u, int tl, int tr) {
  59.     a[edges] = v;
  60.     b[edges] = u;
  61.     int l = tl + N;
  62.     int r = tr + N;
  63.     for (; l <= r; l /= 2, r /= 2) {
  64.         if (l % 2 == 1) {
  65.             add[l++].push_back(edges);
  66.         }
  67.         if (r % 2 == 0) {
  68.             add[r--].push_back(edges);
  69.         }
  70.     }
  71.     ++edges;
  72. }
  73.  
  74. int answer[N];
  75.  
  76. void solve(int v) {
  77.     int saved_size = dsu.size;
  78.     for (int e : add[v]) {
  79.         dsu.merge(a[e], b[e]);
  80.     }
  81.     if (v >= N) {
  82.         int fn = v - N;
  83.         answer[fn] = dsu.s[dsu.get(fn)] - 1;
  84.     } else {
  85.         solve(2 * v);
  86.         solve(2 * v + 1);
  87.     }
  88.     dsu.back_to(saved_size);
  89. }
  90.  
  91. ll number_of_pairs(int n, const vector<vector<int>> &r, const vector<vector<int>> &u) {
  92.     for (int i = 0; i < n; ++i) {
  93.         int last = 0;
  94.         for (int j = 0; j < (int)r[i].size(); ++j) {
  95.             if (last <= i && i <= r[i][j]) {
  96.                 add_edge(i, u[i][j], last, i - 1);
  97.                 add_edge(i, u[i][j], i + 1, r[i][j]);
  98.             } else {
  99.                 add_edge(i, u[i][j], last, r[i][j]);
  100.             }
  101.             last = r[i][j] + 1;
  102.         }
  103.     }
  104.     solve(1);
  105.     //for (int i = 0; i < n; ++i) {
  106.     //  cerr << answer[i] << " ";
  107.     //}
  108.     //cerr << endl;
  109.     return accumulate(answer, answer + n, (ll)0);
  110. }
  111.  
  112. #ifdef LC
  113. int main() {
  114. #ifdef LC
  115.     assert(freopen("input.txt", "r", stdin));
  116. #endif
  117.     ios::sync_with_stdio(0);
  118.     cin.tie(0);
  119.     cout <<
  120.     number_of_pairs(4,
  121.     {{3},{1,3},{2,3},{3}},
  122.     {{1},{0,2},{1,3},{2}})
  123.     << endl;
  124.     return 0;
  125. }
  126. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement