dgc9715

Untitled

Nov 24th, 2019
546
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.56 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #ifdef DGC
  6. #include "debug.h"
  7. #else
  8. #define debug(...) 9715
  9. #endif
  10. typedef long long ll;
  11. typedef long double ld;
  12. typedef complex<ld> point;
  13. #define F first
  14. #define S second
  15.  
  16. struct segment_tree
  17. {
  18.     struct lazy_container
  19.     {
  20.         bool clear;
  21.         ll first, dif;
  22.  
  23.         inline void operator~() // clean lazy
  24.         {
  25.             *this = lazy_container();
  26.         }
  27.  
  28.         inline bool operator()() // has lazy
  29.         {
  30.             return first > 0 || dif > 0 || clear;
  31.         }
  32.  
  33.         lazy_container() : clear(0), first(0), dif(0) {}
  34.         lazy_container(bool clear, ll first, ll dif) : clear(clear), first(first), dif(dif) {}
  35.     };
  36.  
  37.     struct node
  38.     {
  39.         ll x;
  40.         lazy_container lazy;
  41.  
  42.         node() : x(0) {}
  43.  
  44.         inline void apply(int l, int r, const lazy_container &p, int szl) // propagate lazy of p
  45.         {
  46.             if (p.clear)
  47.             {
  48.                 x = 0;
  49.                 ~lazy;
  50.                 lazy.clear = 1;
  51.             }
  52.             int sz = r-l;
  53.             ll first = p.first + szl * p.dif;
  54.             x += first * sz + ((ll)sz-1) * sz / 2 * p.dif;
  55.             lazy.first += first;
  56.             lazy.dif += p.dif;
  57.         }
  58.     };
  59.  
  60. private:
  61.     inline node merge(const node &l, const node &r) const // merge l and r
  62.     {
  63.         node ret;
  64.         ret.x = l.x + r.x;
  65.         return ret;
  66.     }
  67.  
  68.     inline void push(int x, int b, int e, int m)
  69.     {
  70.         if (st[x].lazy())
  71.         {
  72.             st[x + 1].apply(b, m, st[x].lazy, 0);
  73.             st[x + ((m - b) << 1)].apply(m, e, st[x].lazy, m-b);
  74.             ~st[x].lazy;
  75.         }
  76.     }
  77.  
  78.     void update(int x, int b, int e)
  79.     {
  80.         if (lo <= b && e <= hi)
  81.         {
  82.             st[x].apply(b, e, lazy, b-lo);
  83.             return;
  84.         }
  85.  
  86.         int m = (b + e) >> 1;
  87.         int y = x + ((m - b) << 1);
  88.         push(x, b, e, m);
  89.  
  90.         if (lo < m) update(x + 1, b, m);
  91.         if (m < hi) update(y, m, e);
  92.         st[x] = merge(st[x + 1], st[y]);
  93.     }
  94.  
  95.     node query(int x, int b, int e)
  96.     {
  97.         if (lo <= b && e <= hi)
  98.             return st[x];
  99.  
  100.         int m = (b + e) >> 1;
  101.         int y = x + ((m - b) << 1);
  102.         push(x, b, e, m);
  103.  
  104.         if (m >= hi) return query(x + 1, b, m);
  105.         if (m <= lo) return query(y, m, e);
  106.         return merge(query(x + 1, b, m), query(y, m, e));
  107.     }
  108.  
  109.     lazy_container lazy;
  110.     int n, lo, hi;
  111.     vector<node> st;
  112.  
  113. public:
  114.     void update(int l, int r, const lazy_container &x)
  115.     {
  116.         lo = l, hi = r+1, lazy = x;
  117.         update(0, 0, n);
  118.     }
  119.  
  120.     node query(int l, int r)
  121.     {
  122.         lo = l, hi = r+1;
  123.         return query(0, 0, n);
  124.     }
  125.  
  126.     segment_tree(int n) : n(n), st(2 * n - 1) {}
  127. };
  128.  
  129. int main()
  130. {
  131.     #ifdef DGC
  132.         freopen("a.in", "r", stdin);
  133.         //freopen("b.out", "w", stdout);
  134.     #endif
  135.  
  136.     ios_base::sync_with_stdio(0), cin.tie(0);
  137.  
  138.     int n, k;
  139.     cin >> n >> k;
  140.     vector<int> a(n);
  141.     for (auto &i : a) cin >> i;
  142.  
  143.     const int N = 1e6 + 5, L = 2*N + 5;
  144.     segment_tree st(L + 5);
  145.  
  146.     auto solve = [&](const vector<int> &v)
  147.     {
  148.         if (v.empty()) return 0LL;
  149.         st.update(0, L + 5, { 1, 0, 0 });
  150.         st.update(N, L, { 0, 1, 0 });
  151.         ll ret = 0;
  152.         int cur = 0;
  153.         for (auto i : v)
  154.         {
  155.             if (i < 0)
  156.             {
  157.                 ret += st.query(N + cur+i-1, N + cur-2).x;
  158.                 st.update(N + cur+i, N + cur-1, { 0, 1, 1 });
  159.                 st.update(N + cur, L, { 0, -i, 0 });
  160.                 cur += i;
  161.             }
  162.             else
  163.             {
  164.                 ++cur;
  165.                 ret += st.query(N + cur-1, N + cur-1).x;
  166.                 st.update(N + cur, L, { 0, 1, 0 });
  167.             }
  168.         }
  169.         return ret;
  170.     };
  171.  
  172.     vector<vector<int>> pos(k);
  173.     for (int i = 0; i < n; ++i)
  174.         pos[a[i]].push_back(i);
  175.  
  176.     for (auto &p : pos)
  177.     {
  178.         vector<int> aux;
  179.         for (auto i : p)
  180.         {
  181.             if (i > 0 && (aux.empty() || aux.back()+1 != i))
  182.             {
  183.                 int val = i - (aux.empty() ? 0 : (aux.back()+1));
  184.                 aux.push_back(-val);
  185.             }
  186.             aux.push_back(i);
  187.         }
  188.         if (!aux.empty() && aux.back() != n-1)
  189.             aux.push_back(-(n-1-aux.back()));
  190.         cout << solve(aux) << "\n";
  191.     }
  192.  
  193.     return 0;
  194. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment