Dang_Quan_10_Tin

HSGO 2020 PERMSWAP (dsu rollback + Segment Tree)

Jun 29th, 2021 (edited)
1,012
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.44 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. using ll = long long;
  5. using ld = long double;
  6. using ull = unsigned long long;
  7.  
  8. constexpr bool typetest = 0;
  9. constexpr int N = 1e5 + 5;
  10. struct dsurollback
  11. {
  12.     int par[N], ans;
  13.     vector<pair<int, int>> snap;
  14.     dsurollback()
  15.     {
  16.         memset(par, -1, sizeof par);
  17.         snap.reserve(N);
  18.         ans = 0;
  19.     }
  20.     int findpar(int v)
  21.     {
  22.         while (par[v] > 0 && (v = par[v]))
  23.             ;
  24.         return v;
  25.     }
  26.  
  27.     void Merge(int u, int v)
  28.     {
  29.         u = findpar(u);
  30.         v = findpar(v);
  31.  
  32.         if (u == v)
  33.             return;
  34.  
  35.         if (par[u] < par[v])
  36.             swap(u, v);
  37.  
  38.         ++ans;
  39.  
  40.         snap.emplace_back(u, par[u]);
  41.  
  42.         par[v] += par[u];
  43.         par[u] = v;
  44.     }
  45.  
  46.     void rollback(int sz)
  47.     {
  48.         while (sz < (int)snap.size())
  49.         {
  50.             par[par[snap.back().first]] -= snap.back().second;
  51.             par[snap.back().first] = snap.back().second;
  52.             --ans;
  53.             snap.pop_back();
  54.         }
  55.     }
  56. } f;
  57.  
  58. vector<pair<int, int>> s;
  59. int p[N], a[N];
  60. int n, m;
  61. int x[N], y[N];
  62. vector<int> adj[N * 2];
  63. vector<pair<int, int>> st[N * 2];
  64.  
  65. void Read()
  66. {
  67.     cin >> n >> m;
  68.     s.reserve(n + m * 2);
  69.     for (int i = 1; i <= n; ++i)
  70.     {
  71.         cin >> p[i];
  72.         s.emplace_back(i, p[i]);
  73.         a[i] = p[i];
  74.     }
  75.  
  76.     for (int i = 1; i <= m; ++i)
  77.     {
  78.         cin >> x[i] >> y[i];
  79.         if (x[i] != y[i])
  80.         {
  81.             swap(a[x[i]], a[y[i]]);
  82.             s.emplace_back(x[i], a[x[i]]);
  83.             s.emplace_back(y[i], a[y[i]]);
  84.         }
  85.     }
  86. }
  87.  
  88. #define Find(x, y) (lower_bound(x.begin(), x.end(), y) - x.begin() + 1)
  89.  
  90. void Update(int id, int l, int r, const int &a, const int &b, const pair<int, int> &x)
  91. {
  92.     if (l > b || r < a)
  93.         return;
  94.     if (l >= a && r <= b)
  95.     {
  96.         st[id].emplace_back(x);
  97.         return;
  98.     }
  99.  
  100.     Update(id << 1, l, (l + r) / 2, a, b, x);
  101.     Update(id << 1 | 1, (l + r) / 2 + 1, r, a, b, x);
  102. }
  103.  
  104. void DAC(int id, int l, int r)
  105. {
  106.     int shot = f.snap.size();
  107.  
  108.     for (auto i : st[id])
  109.         f.Merge(i.first, i.second);
  110.  
  111.     if (l == r)
  112.     {
  113.         cout << f.ans << "\n";
  114.         f.rollback(shot);
  115.         return;
  116.     }
  117.  
  118.     DAC(id << 1, l, (l + r) / 2);
  119.     DAC(id << 1 | 1, (l + r) / 2 + 1, r);
  120.  
  121.     f.rollback(shot);
  122. }
  123.  
  124. void Solve()
  125. {
  126.     sort(s.begin(), s.end());
  127.     s.resize(unique(s.begin(), s.end()) - s.begin());
  128.  
  129.     for (int i = 1; i <= n; ++i)
  130.     {
  131.         adj[Find(s, make_pair(i, p[i]))].emplace_back(0);
  132.         a[i] = p[i];
  133.     }
  134.  
  135.     for (int i = 1; i <= m; ++i)
  136.         if (x[i] != y[i])
  137.         {
  138.             adj[Find(s, make_pair(x[i], a[x[i]]))].emplace_back(i);
  139.             adj[Find(s, make_pair(y[i], a[y[i]]))].emplace_back(i);
  140.             swap(a[x[i]], a[y[i]]);
  141.             adj[Find(s, make_pair(x[i], a[x[i]]))].emplace_back(i);
  142.             adj[Find(s, make_pair(y[i], a[y[i]]))].emplace_back(i);
  143.         }
  144.  
  145.     for (int i = 1; i <= (int)s.size(); ++i)
  146.         for (int j = 0; j < (int)adj[i].size(); j += 2)
  147.             Update(1, 1, m, adj[i][j], (j == ((int)adj[i].size() - 1)) ? m : (adj[i][j + 1] - 1), s[i - 1]);
  148.  
  149.     DAC(1, 1, m);
  150. }
  151.  
  152. int32_t main()
  153. {
  154.     ios::sync_with_stdio(0);
  155.     cin.tie(0);
  156.     cout.tie(0);
  157.     int t(1);
  158.     if (typetest)
  159.         cin >> t;
  160.     for (int _ = 1; _ <= t; ++_)
  161.     {
  162.         Read();
  163.         Solve();
  164.     }
  165. }
Add Comment
Please, Sign In to add comment