Advertisement
Ikmik

mega inversions count

Oct 26th, 2016
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.66 KB | None | 0 0
  1. template<class T, class iter>
  2. class inversion_counter {
  3.     vector<iter> sorted;
  4.     vector<iter> additional;
  5.     vector<uint64_t> ans;
  6.     vector<vector<uint64_t>::iterator> sorted_ans;
  7.     vector<vector<uint64_t>::iterator> additional_ans;
  8.     void count(const iter& a, const iter& b,
  9.                typename vector<iter>::iterator sl, typename vector<iter>::iterator sr,
  10.                vector<vector<uint64_t>::iterator>::iterator al, vector<vector<uint64_t>::iterator>::iterator ar) {
  11.         if (distance(sl, sr) <= 1) {
  12.             if (sl != sr) {
  13.                 *sl = a;
  14.                 *al = ans.begin() + distance(sorted.begin(), sl);
  15.             }
  16.             return;
  17.         }
  18.         iter mid = next(a, distance(a, b) / 2);
  19.         typename vector<iter>::iterator sm = next(sl, distance(a, b) / 2);
  20.         vector<vector<uint64_t>::iterator>::iterator am = next(al, distance(a, b) / 2);
  21.         count(a, mid, sl, sm, al, am);
  22.         count(mid, b, sm, sr, am, ar);
  23.         typename vector<iter>::iterator it = sl, jt = sm;
  24.         typename vector<iter>::iterator vi = additional.begin();
  25.         vector<vector<uint64_t>::iterator>::iterator ai = al, aj = am;
  26.         vector<vector<uint64_t>::iterator>::iterator avi = additional_ans.begin();
  27.         while (it != sm || jt != sr) {
  28.             if ((jt != sr) && (it == sm || **jt < **it)) {
  29.                 *(vi++) = *jt;
  30.                 **aj += distance(it, sm);
  31.                 *(avi++) = *aj;
  32.                 aj++;
  33.                 jt++;
  34.             } else {
  35.                 *(vi++) = *it;
  36.                 *(avi++) = *ai;
  37.                 ai++;
  38.                 it++;
  39.             }
  40.         }
  41.         copy(additional.begin(), vi, sl);
  42.         copy(additional_ans.begin(), avi, al);
  43.     }
  44.   public:
  45.     inversion_counter(const iter& a, const iter& b) {
  46.         sorted.resize(distance(a, b));
  47.         additional.resize(distance(a, b));
  48.         ans.resize(distance(a, b), 0);
  49.         sorted_ans.resize(distance(a, b));
  50.         additional_ans.resize(distance(a, b));
  51.         count(a, b, all(sorted), all(sorted_ans));
  52.     }
  53.     const vector<uint64_t>& operator()() const {
  54.         return ans;
  55.     }
  56. };
  57.  
  58. template<class T>
  59. uint64_t mega_inversion_count(const vector<T>& vec) {
  60.     vector<uint64_t> frw_inv = inversion_counter<T, typename vector<T>::const_iterator>(all(vec))();
  61.     vector<uint64_t> bkw_inv = inversion_counter<T, typename vector<T>::const_reverse_iterator>(rall(vec))();
  62.     forn(i, vec.size()) {
  63.         bkw_inv[i] = i - bkw_inv[i];
  64.     }
  65.     reverse(all(bkw_inv));
  66.     uint64_t ans = 0;
  67.     forn(i, vec.size()) {
  68.         ans += frw_inv[i] * bkw_inv[i];
  69.     }
  70.     return ans;
  71. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement