Advertisement
nicuvlad76

Untitled

Nov 21st, 2018
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.31 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cassert>
  6. #include <set>
  7.  
  8. using namespace std;
  9.  
  10. static const int kModulo  = 1000 * 1000 * 1000 + 7;
  11.  
  12. // ax + b
  13. struct Function {
  14.     Function(int64_t _a = 0, int64_t _b = 0):
  15.         a(_a),
  16.         b(_b) {}
  17.  
  18.     int64_t a;
  19.     int64_t b;
  20.  
  21.     int operator()(int x) const {
  22.         return (a % kModulo * x + b) % kModulo;
  23.     }
  24.  
  25.     Function& operator+=(const Function& that) {
  26.         a += that.a;
  27.         b += that.b;
  28.         return *this;
  29.     }
  30. };
  31.  
  32. // axy + bx + cy + d
  33. struct Function2 {
  34.     Function2(int64_t _a = 0, int64_t _b = 0, int64_t _c = 0, int64_t _d = 0):
  35.         a(_a),
  36.         b(_b),
  37.         c(_c),
  38.         d(_d) {}
  39.  
  40.     int64_t a;
  41.     int64_t b;
  42.     int64_t c;
  43.     int64_t d;
  44.  
  45.     int operator()(int x, int y) const {
  46.         return (1LL * a * x % kModulo * y + 1LL * b * x + 1LL * c * y + d) % kModulo;
  47.     }
  48.  
  49.     Function2& operator+=(const Function2& that) {
  50.         a += that.a;
  51.         b += that.b;
  52.         c += that.c;
  53.         d += that.d;
  54.         return *this;
  55.     }
  56. };
  57.  
  58. template<class T>
  59. class FenwickTree {
  60.   public:
  61.     FenwickTree(int size):
  62.         m_data(size) {}
  63.  
  64.     int size() const {
  65.         return m_data.size();
  66.     }
  67.  
  68.     void add(int pos, const T& to_add) {
  69.         for (++pos; pos <= size(); pos += (pos & -pos))
  70.             m_data[pos - 1] += to_add;
  71.     }
  72.  
  73.     T query(int pos) {
  74.         T answer;
  75.         for (++pos; pos > 0; pos -= (pos & -pos))
  76.             answer += m_data[pos - 1];
  77.         return answer;
  78.     }
  79.  
  80.   private:
  81.     vector<T> m_data;
  82. };
  83.  
  84. class Solver {
  85.   public:
  86.     Solver(vector<int> V):
  87.         m_values(V),
  88.         m_last(V.size(), -1),
  89.         m_next(V.size(), V.size()),
  90.         m_fenwick_tree(V.size()),
  91.         m_fenwick_tree2(V.size()),
  92.         m_total_cost(0),
  93.         m_pos(V.size())
  94.     {}
  95.  
  96.     int total_cost() {
  97.         vector<int> where(size(), -1);
  98.         for (int i = 0; i < size(); ++i) {
  99.             m_last[i] = where[m_values[i]];
  100.             where[m_values[i]] = i;
  101.         }
  102.  
  103.         fill(where.begin(), where.end(), size());
  104.         for (int i = size() - 1; i >= 0; --i) {
  105.             m_next[i] = where[m_values[i]];
  106.             where[m_values[i]] = i;
  107.         }
  108.  
  109.         divide(0, size());
  110.  
  111.         for (int i = 0; i < size(); ++i) {
  112.             int min_begin = m_last[i] + 1;
  113.             int max_begin = i;
  114.             int min_end = i;
  115.  
  116.             m_total_cost = (m_total_cost + static_cast<int64_t>(max_begin - min_begin + 1) * (size() - min_end) % kModulo * (m_values[i] + 1)) % kModulo;
  117.         }
  118.  
  119.         return m_total_cost;
  120.     }
  121.  
  122.     int size() const {
  123.         return m_values.size();
  124.     }
  125.  
  126.   private:
  127.     void divide(int from, int to) {
  128.         if (to - from == 1)
  129.             return;
  130.         int mid = (from + to) / 2;
  131.         divide(from, mid);
  132.         divide(mid, to);
  133.  
  134.         // we have i in [from, mid) and j in [mid, to)
  135.         case1(from, mid, to);
  136.         case2(from, mid, to);
  137.         case3(from, mid, to);
  138.         case4(from, mid, to);
  139.     }
  140.  
  141.     void case1(int from, int mid, int to) {
  142.         // case 1, V[i] < V[j] and last[j] <= last[i]
  143.         for (int i = from; i < to; ++i)
  144.             m_pos[i] = i;
  145.         sort(m_pos.begin() + from, m_pos.begin() + to, [&](int x, int y) {
  146.             if (m_last[x] != m_last[y])
  147.                 return m_last[x] < m_last[y];
  148.             return m_values[x] > m_values[y];
  149.         });
  150.  
  151.         for (int i = to - 1; i >= from; --i) {
  152.             int x = m_pos[i];
  153.             if (m_last[x] >= mid)
  154.                 continue;
  155.             if (x >= mid) {
  156.                 auto f = m_fenwick_tree.query(m_values[x] - 1);
  157.                 m_total_cost = (m_total_cost + 1LL * f(x) * (m_values[x] + 1)) % kModulo;
  158.             } else {
  159.                 m_fenwick_tree.add(m_values[x], Function{m_last[x] - x, 1LL * (x - m_last[x]) * size()});
  160.             }
  161.         }
  162.  
  163.         for (int i = to - 1; i >= from; --i) {
  164.             int x = m_pos[i];
  165.             if (m_last[x] >= mid)
  166.                 continue;
  167.             if (x < mid)
  168.                 m_fenwick_tree.add(m_values[x], Function{x - m_last[x], 1LL * (m_last[x] - x) * size()});
  169.         }
  170.     }
  171.  
  172.     void case2(int from, int mid, int to) {
  173.         // case 2, V[i] < V[j] and last[j] > last[i]
  174.         // luckily the order in which we process is reverse of case 1
  175.         set<int> to_erase;
  176.         for (int i = from; i < to; ++i) {
  177.             int x = m_pos[i];
  178.             if (m_last[x] >= mid)
  179.                 continue;
  180.  
  181.             while (!to_erase.empty() && *to_erase.begin() <= m_last[x]) {
  182.                 int y = *to_erase.begin();
  183.                 to_erase.erase(y);
  184.                 m_fenwick_tree2.add(m_values[y], Function2{-1, +y, +size(), -1LL * y * size()});
  185.             }
  186.  
  187.             if (x >= mid) {
  188.                 auto f = m_fenwick_tree2.query(m_values[x] - 1);
  189.                 m_total_cost = (m_total_cost + 1LL * f(x, m_last[x]) * (m_values[x] + 1)) % kModulo;
  190.             } else {
  191.                 m_fenwick_tree2.add(m_values[x], Function2{1, -x, -size(), 1LL * x * size()});
  192.                 to_erase.insert(x);
  193.             }
  194.         }
  195.  
  196.         for (auto &x : to_erase) {
  197.             m_fenwick_tree2.add(m_values[x], Function2{-1, +x, +size(), -1LL * x * size()});
  198.         }
  199.     }
  200.  
  201.     void case3(int from, int mid, int to) {
  202.         // V[i] > V[j], and last[j] <= last[i]
  203.         for (int i = from; i < to; ++i) {
  204.             int x = m_pos[i];
  205.             if (m_last[x] >= mid)
  206.                 continue;
  207.             if (x >= mid) {
  208.                 m_fenwick_tree.add(m_values[x], Function{size() - x, 0});
  209.             } else {
  210.                 auto f = m_fenwick_tree.query(m_values[x] - 1);
  211.                 m_total_cost = (m_total_cost + 1LL * f(x - m_last[x]) % kModulo * (m_values[x] + 1)) % kModulo;
  212.             }
  213.         }
  214.  
  215.         for (int i = from; i < to; ++i) {
  216.             int x = m_pos[i];
  217.             if (m_last[x] >= mid)
  218.                 continue;
  219.             if (x >= mid) {
  220.                 m_fenwick_tree.add(m_values[x], Function{x - size(), 0});
  221.             }
  222.         }
  223.     }
  224.  
  225.     void case4(int from, int mid, int to) {
  226.         // V[i] > V[j], and last[j] > last[i]
  227.         set<int> to_add;
  228.         for (int i = from; i < to; ++i) {
  229.             int x = m_pos[i];
  230.             if (m_last[x] >= mid)
  231.                 continue;
  232.  
  233.             while (!to_add.empty() && *to_add.begin() <= m_last[x]) {
  234.                 int y = *to_add.begin();
  235.                 to_add.erase(y);
  236.                 auto f = m_fenwick_tree.query(m_values[y] - 1);
  237.                 m_total_cost = (m_total_cost + 1LL * f(y) * (m_values[y] + 1)) % kModulo;
  238.             }
  239.  
  240.             if (x >= mid) {
  241.                 m_fenwick_tree.add(m_values[x], Function{size() - x, -1LL * m_last[x] * (size() - x)});
  242.             } else {
  243.                 // decrease now, we'll fix it later
  244.                 auto f = m_fenwick_tree.query(m_values[x] - 1);
  245.                 m_total_cost = (m_total_cost - 1LL * f(x) * (m_values[x] + 1)) % kModulo;
  246.                 m_total_cost = (m_total_cost + kModulo) % kModulo;
  247.                 to_add.insert(x);
  248.             }
  249.         }
  250.  
  251.         while (!to_add.empty()) {
  252.             int y = *to_add.rbegin();
  253.             to_add.erase(y);
  254.             auto f = m_fenwick_tree.query(m_values[y] - 1);
  255.             m_total_cost = (m_total_cost + 1LL * f(y) * (m_values[y] + 1)) % kModulo;
  256.         }
  257.  
  258.         for (int i = from; i < to; ++i) {
  259.             int x = m_pos[i];
  260.             if (m_last[x] >= mid)
  261.                 continue;
  262.             if (x >= mid) {
  263.                 m_fenwick_tree.add(m_values[x], Function{x - size(), 1LL * m_last[x] * (size() - x)});
  264.             }
  265.         }
  266.     }
  267.  
  268.     vector<int> m_values, m_last, m_next;
  269.     FenwickTree<Function> m_fenwick_tree;
  270.     FenwickTree<Function2> m_fenwick_tree2;
  271.     int m_total_cost;
  272.     vector<int> m_pos;
  273. };
  274.  
  275. int main() {
  276.     ifstream cin("sortall.in");
  277.     ofstream cout("sortall.out");
  278.  
  279.     int N; assert(cin >> N);
  280.     assert(1 <= N && N <= 100 * 1000);
  281.     vector<int> V(N);
  282.     for (int i = 0; i < N; ++i) {
  283.         assert(cin >> V[i]);
  284.         assert(1 <= V[i] && V[i] <= N);
  285.         --V[i];
  286.     }
  287.  
  288.     Solver S(V);
  289.     cout << S.total_cost() << "\n";
  290. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement