leoanjos

Inversion Counting

Mar 2nd, 2023 (edited)
749
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.17 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define llong long long int
  6.  
  7. const int SQRT = 350;
  8.  
  9. struct FenwickTree {
  10. private:
  11.     int n;
  12.     vector<int> tree;
  13.  
  14. public:
  15.     FenwickTree(int n) {
  16.         this->n = n + 1;
  17.         tree.assign(n + 1, 0);
  18.     }
  19.  
  20.     void add(int i, int v) {
  21.         if (!i) tree[0] += v;
  22.         else {
  23.             while (i < n) {
  24.                 tree[i] += v;
  25.                 i += LSO(i);
  26.             }
  27.         }
  28.     }
  29.  
  30.     int sum(int i, int j) {
  31.         return sum(j) - sum(i - 1);
  32.     }
  33.  
  34. private:
  35.     int LSO(int i) {
  36.         return i & -i;
  37.     }
  38.  
  39.     int sum(int i) {
  40.         if (i < 0) return 0;
  41.  
  42.         int ans = tree[0];
  43.         while (i) {
  44.             ans += tree[i];
  45.             i -= LSO(i);
  46.         }
  47.  
  48.         return ans;
  49.     }
  50. };
  51.  
  52. int main() {
  53.     ios_base::sync_with_stdio(false);
  54.     cin.tie(NULL);
  55.  
  56.     int N, K, Q;
  57.     cin >> N >> K >> Q;
  58.  
  59.     llong invs = 0LL;
  60.     FenwickTree tree(K);
  61.     vector<vector<int>> pos(K + 1, vector<int>());
  62.  
  63.     for (int i = 0; i < N; i++) {
  64.         int a; cin >> a;
  65.         pos[a].push_back(i);
  66.  
  67.         invs += tree.sum(a + 1, K);
  68.         tree.add(a, 1);
  69.     }
  70.  
  71.     vector<int> heavy, idx(K + 1, -1);
  72.     for (int i = 1; i <= K; i++)
  73.         if ((int) pos[i].size() > SQRT) {
  74.             idx[i] = heavy.size();
  75.             heavy.push_back(i);
  76.         }
  77.  
  78.     int size = heavy.size();
  79.     vector<vector<llong>> diff(size, vector<llong>(size, 0LL));
  80.  
  81.     for (int i = 0; i < size; i++)
  82.         for (int j = 0; j < size; j++) {
  83.             if (i == j) continue;
  84.  
  85.             int idx = 0;
  86.             for (int k = 0; k < (int) pos[heavy[i]].size(); k++) {
  87.                 while (idx < (int) pos[heavy[j]].size() && pos[heavy[j]][idx] < pos[heavy[i]][k]) idx++;
  88.                 diff[i][j] += (int) pos[heavy[j]].size() - 2 * idx;
  89.             }
  90.         }
  91.  
  92.     vector<int> id(K + 1);
  93.     for (int i = 1; i <= K; i++)
  94.         id[i] = i;
  95.  
  96.     vector<map<int, llong>> memo(K + 1);
  97.     while (Q--) {
  98.         int i; cin >> i;
  99.  
  100.         llong d = 0LL;
  101.         if (memo[id[i]].count(id[i + 1])) d = memo[id[i]][id[i + 1]];
  102.         else if (idx[id[i]] != -1 && idx[id[i + 1]] != -1) d = diff[idx[id[i]]][idx[id[i + 1]]];
  103.         else if (idx[id[i]] == -1 && idx[id[i + 1]] == -1) {
  104.             int j = id[i], k = id[i + 1], idx = 0;
  105.             for (int l = 0; l < (int) pos[j].size(); l++) {
  106.                 while (idx < (int) pos[k].size() && pos[k][idx] < pos[j][l]) idx++;
  107.                 d += (int) pos[k].size() - 2 * idx;
  108.             }
  109.         }
  110.         else {
  111.             bool swapped = false;
  112.             int j = id[i], k = id[i + 1];
  113.  
  114.             if (idx[j] != -1) {
  115.                 swap(j, k);
  116.                 swapped = true;
  117.             }
  118.  
  119.             for (int p: pos[j]) {
  120.                 int idx = upper_bound(pos[k].begin(), pos[k].end(), p) - pos[k].begin();
  121.                 if (!swapped) d += (int) pos[k].size() - 2 * idx;
  122.                 else d -= (int) pos[k].size() - 2 * idx;
  123.             }
  124.         }
  125.  
  126.         invs += d;
  127.         cout << invs << "\n";
  128.  
  129.         memo[id[i]][id[i + 1]] = d;
  130.         swap(id[i], id[i + 1]);
  131.     }
  132. }
Advertisement
Add Comment
Please, Sign In to add comment