Advertisement
dgc9715

Untitled

Nov 23rd, 2019
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.60 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 node
  19.     {
  20.         bool cle;
  21.         ll x, add, p, sh;
  22.  
  23.         inline void build()
  24.         {
  25.             cle = 0;
  26.             x = 0;
  27.             clean_lazy();
  28.         }
  29.  
  30.         inline bool has_lazy()
  31.         {
  32.             return add > 0 || p > 0 || sh > 0 || cle;
  33.         }
  34.  
  35.         inline void clean_lazy()
  36.         {
  37.             cle = 0;
  38.             add = 0, p = 0, sh = 0;
  39.         }
  40.     };
  41.  
  42.     struct update_info
  43.     {
  44.         ll x;
  45.         bool pa;
  46.     };
  47.  
  48. private:
  49.  
  50.     // merge l and r into u
  51.     inline void merge(node &u, node &l, node &r)
  52.     {
  53.         u.x = l.x + r.x;
  54.     }
  55.  
  56.     // propagate lazy of p into u
  57.     inline void prop(node &p, node &u, int szu, int szl)
  58.     {
  59.         if (p.cle)
  60.         {
  61.             u.x = 0;
  62.             u.clean_lazy();
  63.             u.cle = 1;
  64.         }
  65.         u.x += p.add * szu;
  66.         ll fi = p.p + szl * p.sh;
  67.         u.x += fi * szu + ((ll)szu-1) * szu / 2 * p.sh;
  68.         u.add += p.add;
  69.         u.p += fi;
  70.         u.sh += p.sh;
  71.     }
  72.  
  73.     // update u with x
  74.     inline void apply(node &u, update_info &x, int b, int e, int lo, int hi)
  75.     {
  76.         if (!x.pa)
  77.         {
  78.             u.x += (e-b) * x.x;
  79.             u.add += x.x;
  80.         }
  81.         else
  82.         {
  83.             ll fi = 1 + b-lo;
  84.             ll to = fi + e-b-1;
  85.             u.x += to * (to+1) / 2 - (fi-1) * fi / 2;
  86.             u.p += fi;
  87.             ++u.sh;
  88.         }
  89.     }
  90.  
  91.     inline void push(node &u, int b, int e, int m)
  92.     {
  93.         if (u.has_lazy())
  94.         {
  95.             prop(u, st[id(b, m)], m-b, 0);
  96.             prop(u, st[id(m, e)], e-m, m-b);
  97.             u.clean_lazy();
  98.         }
  99.     }
  100.  
  101.     inline int id(int b, int e) { return (b+e-1) | (b!=e-1); }
  102.  
  103.     void build(int b, int e)
  104.     {
  105.         node &cur = st[id(b, e)];
  106.  
  107.         if (b+1 == e)
  108.         {
  109.             cur.build();
  110.             return;
  111.         }
  112.  
  113.         int m = (b+e+1)>>1;
  114.         build(b, m);
  115.         build(m, e);
  116.         merge(cur, st[id(b, m)], st[id(m, e)]);
  117.     }
  118.  
  119.     void update(int b, int e, int lo, int hi, update_info &x)
  120.     {
  121.         node &cur = st[id(b, e)];
  122.  
  123.         if (lo <= b && e <= hi)
  124.         {
  125.             apply(cur, x, b, e, lo, hi);
  126.             return;
  127.         }
  128.  
  129.         int m  = (b+e+1)>>1;
  130.         push(cur, b, e, m);
  131.  
  132.         if (lo < m) update(b, m, lo, hi, x);
  133.         if (m < hi) update(m, e, lo, hi, x);
  134.         merge(cur, st[id(b, m)], st[id(m, e)]);
  135.     }
  136.  
  137.     ll query(int b, int e, int lo, int hi)
  138.     {
  139.         node &cur = st[id(b, e)];
  140.  
  141.         if (lo <= b && e <= hi)
  142.             return cur.x;
  143.  
  144.         int m = (b+e+1)>>1;
  145.         push(cur, b, e, m);
  146.  
  147.         ll ret = 0;
  148.         if (lo < m) ret += query(b, m, lo, hi);
  149.         if (m < hi) ret += query(m, e, lo, hi);
  150.         return ret;
  151.     }
  152.  
  153.     int n;
  154.     vector<node> st;
  155.  
  156. public:
  157.     void build()
  158.     {
  159.         build(0, n);
  160.     }
  161.  
  162.     void update(int lo, int hi, update_info x)
  163.     {
  164.         //debug("update", lo, hi, x.x, x.pa);
  165.         update(0, n, lo, hi+1, x);
  166.     }
  167.  
  168.     ll query(int lo, int hi)
  169.     {
  170.         //debug("query", lo, hi);
  171.         return query(0, n, lo, hi+1);
  172.     }
  173.  
  174.     void clear()
  175.     {
  176.         st[id(0, n)].x = 0;
  177.         st[id(0, n)].clean_lazy();
  178.         st[id(0, n)].cle = true;
  179.     }
  180.  
  181.     segment_tree(int n) : n(n), st(2*n) {}
  182. };
  183.  
  184. ll brute(vector<int> a, int k)
  185. {
  186.     ll r = 0;
  187.     int n = a.size();
  188.     for (int i = 0; i < n; ++i)
  189.     {
  190.         int s = 0;
  191.         for (int j = i; j < n; ++j)
  192.         {
  193.             s += (a[j] == k) ? +1 : -1;
  194.             r += s > 0;
  195.         }
  196.     }
  197.     return r;
  198. }
  199.  
  200. int main()
  201. {
  202.     #ifdef DGC
  203.         freopen("a.in", "r", stdin);
  204.         //freopen("b.out", "w", stdout);
  205.     #endif
  206.  
  207.     ios_base::sync_with_stdio(0), cin.tie(0);
  208.  
  209.     int n, k;
  210.     cin >> n >> k;
  211.     vector<int> a(n);
  212.     for (auto &i : a) cin >> i;
  213.  
  214.     const int N = 1e6 + 5, L = 2*N + 5;
  215.     segment_tree st(2*N + 10);
  216.     st.build();
  217.  
  218.     auto solve = [&](vector<int> v)
  219.     {
  220.         //debug("solve", v);
  221.         st.clear();
  222.         st.update(N, L, { 1, false });
  223.         ll ret = 0;
  224.         int cur = 0;
  225.         for (auto i : v)
  226.         {
  227.             if (i < 0)
  228.             {
  229.                 ret += st.query(N + cur+i-1, N + cur-2);
  230.                 st.update(N + cur+i, N + cur-1, { 1, true });
  231.                 st.update(N + cur, L, { -i, false });
  232.                 cur += i;
  233.             }
  234.             else
  235.             {
  236.                 ++cur;
  237.                 ret += st.query(N + cur-1, N + cur-1);
  238.                 //debug(cur, ret);
  239.                 st.update(N + cur, L, { 1, false });
  240.             }
  241.         }
  242.         return ret;
  243.     };
  244.  
  245.     vector<vector<int>> pos(k);
  246.     for (int i = 0; i < n; ++i)
  247.         pos[a[i]].push_back(i);
  248.  
  249.     vector<ll> ans(k);
  250.     for (auto &p : pos)
  251.     {
  252.         vector<int> aux;
  253.         int sz = p.size();
  254.         if (!sz) continue;
  255.         for (auto i : p)
  256.         {
  257.             if (i > 0 && (aux.empty() || aux.back()+1 != i))
  258.             {
  259.                 int val = i - (aux.empty() ? 0 : (aux.back()+1));
  260.                 aux.push_back(-val);
  261.             }
  262.             aux.push_back(i);
  263.         }
  264.         if (aux.back() != n-1)
  265.             aux.push_back(-(n-1-aux.back()));
  266.         ans[&p-&pos[0]] = solve(aux);
  267.     }
  268.  
  269.     //cout << clock() * 1000 / CLOCKS_PER_SEC << endl; return 0;
  270.     for (auto &i : ans)
  271.         cout << i << "\n";
  272.  
  273.     /*cout << endl;
  274.     for (int i = 0; i < k; ++i)
  275.         cout << brute(a, i) << "\n";*/
  276.  
  277.     return 0;
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement