Advertisement
Kevin_Zhang

Untitled

Mar 10th, 2020
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.22 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #define pb emplace_back
  3. using namespace std;
  4. using ll = long long;
  5. const int maxn = 500010, inf = maxn;
  6. int n, a[maxn], _c[maxn], nxt[maxn], rb[maxn], rg[maxn], k;
  7. ll res;
  8. struct sgt {
  9.     int v[maxn<<1];
  10.     void init(){ fill(v, v+(maxn<<1), n); };
  11.     void modify(int i, int pos) {
  12.         for (i += n;i;i >>= 1)
  13.             v[i] = min(v[i], pos);
  14.     }
  15.     int query(int l, int r) {
  16.         int res = n;
  17.         for (l += n, r += n;l < r;l >>= 1, r >>= 1) {
  18.             if (l&1) res = min(res, v[l++]);
  19.             if (r&1) res = min(res, v[--r]);
  20.         }
  21.         return res;
  22.     }
  23.     void reset(){ fill(v, v+(maxn<<1), 0); };
  24.     void add(int i) { for (++i;i <= n;i += i & -i) ++v[i]; }
  25.     int query(int k) {
  26.         int res = 0;
  27.         for (int i = 19;i >= 0;--i) {
  28.             if (((1<<i) | res) <= n && v[(1<<i) | res] < k)
  29.                 k -= v[res |= 1<<i];
  30.         }
  31.         return res-1;
  32.     }
  33.     int qsum(int i) {
  34.         int res = 0;
  35.         for (++i;i;i ^= i & -i) res += v[i];
  36.         return res;
  37.     }
  38. }vtree;
  39. void make_nxt_small() {
  40.     static vector<int> query[maxn];
  41.     vtree.init();
  42.     for (int i = 0;i < n;++i)
  43.         query[ nxt[i] ].pb(i);
  44.     for (int i = n;i >= 0;--i) {
  45.         for (int u : query[i])
  46.             rb[u] = vtree.query(0, a[u]);
  47.         vtree.modify(a[i], i);
  48.     }
  49. }
  50. void get_ans() {
  51.     static bool cnt[maxn];
  52.     vtree.reset();
  53.     vector<int> v(n);
  54.     for (int i = n-1;i >= 0;--i) {
  55.         if (nxt[i] != i+1 && !cnt[nxt[i]]) vtree.add(nxt[i]), cnt[nxt[i]] = true;//, cout << "add " << nxt[i] << '\n';
  56.         if (vtree.qsum(rg[i])+1 < k) continue;
  57.         v[i] = min(rg[i]+1, vtree.query(k)) - max(i-1, vtree.query(k-1));
  58.  
  59.         res += min(rg[i]+1, vtree.query(k)) - max(i-1, vtree.query(k-1));
  60.     }
  61. //  cout << "V\n";
  62. //  for (int i = 0;i < n;++i)
  63. //      cout << v[i] << " \n"[i==n-1];
  64. //  cout << '\n';
  65. }
  66. signed main(){
  67.     ios_base::sync_with_stdio(0), cin.tie(0);
  68.     cin >> n >> k;
  69.     for (int i = 0;i < n;++i)
  70.         cin >> a[i];
  71.     vtree.init();
  72.     iota(_c, _c+n, 0);
  73.     sort(_c, _c+n, [&](int x, int y) { return a[x] < a[y]; });
  74.     for (int i = 0;i < n;++i)
  75.         a[ _c[i] ] = i;
  76.     for (int i = n-1;i >= 0;--i) {
  77.         nxt[i] = vtree.query(a[i]+1, n);
  78.         vtree.modify(a[i], i);
  79.     }
  80.     make_nxt_small();
  81.     rg[n] = n;
  82.     for (int i = n-1;i >= 0;--i) {
  83.         if (rg[i+1] < nxt[i]-1) rg[i] = rg[i+1];
  84.         else rg[i] = min(rb[i]-1, rg[ nxt[i] ]);
  85.     }
  86.     get_ans();
  87.     cout << res << '\n';
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement