QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#311808#4780. 完美的队列hos_lyric0 0ms0kbC++1413.8kb2024-01-22 20:24:052024-01-22 20:24:06

Judging History

你现在查看的是最新测评结果

  • [2024-01-22 20:24:06]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2024-01-22 20:24:05]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")


// T: monoid representing information of an interval.
//   T()  should return the identity.
//   T(S s)  should represent a single element of the array.
//   T::pull(const T &l, const T &r)  should pull two intervals.
template <class T> struct SegmentTreePoint {
  int logN, n;
  vector<T> ts;
  SegmentTreePoint() : logN(0), n(0) {}
  explicit SegmentTreePoint(int n_) {
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
  }
  template <class S> explicit SegmentTreePoint(const vector<S> &ss) {
    const int n_ = ss.size();
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
    for (int i = 0; i < n_; ++i) at(i) = T(ss[i]);
    build();
  }
  T &at(int i) {
    return ts[n + i];
  }
  void build() {
    for (int u = n; --u; ) pull(u);
  }

  inline void pull(int u) {
    ts[u].pull(ts[u << 1], ts[u << 1 | 1]);
  }

  // Changes the value of point a to s.
  template <class S> void change(int a, const S &s) {
    assert(0 <= a); assert(a < n);
    ts[a += n] = T(s);
    for (; a >>= 1; ) pull(a);
  }

  // Applies T::f(args...) to point a.
  template <class F, class... Args>
  void ch(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a < n);
    (ts[a += n].*f)(args...);
    for (; a >>= 1; ) pull(a);
  }

  // Calculates the product for [a, b).
  T get(int a, int b) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return T();
    a += n; b += n;
    T prodL, prodR, t;
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) { t.pull(prodL, ts[aa++]); prodL = t; }
      if (bb & 1) { t.pull(ts[--bb], prodR); prodR = t; }
    }
    t.pull(prodL, prodR);
    return t;
  }

  // Calculates T::f(args...) of a monoid type for [a, b).
  //   op(-, -)  should calculate the product.
  //   e()  should return the identity.
  template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
  auto
#else
  decltype((std::declval<T>().*F())())
#endif
  get(int a, int b, Op op, E e, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return e();
    a += n; b += n;
    auto prodL = e(), prodR = e();
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) prodL = op(prodL, (ts[aa++].*f)(args...));
      if (bb & 1) prodR = op((ts[--bb].*f)(args...), prodR);
    }
    return op(prodL, prodR);
  }

  // Find min b s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from left to right.
  //   Returns n + 1 if there is no such b.
  template <class F, class... Args>
  int findRight(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a <= n);
    if ((T().*f)(args...)) return a;
    if (a == n) return n + 1;
    a += n;
    for (; ; a >>= 1) if (a & 1) {
      if ((ts[a].*f)(args...)) {
        for (; a < n; ) {
          if (!(ts[a <<= 1].*f)(args...)) ++a;
        }
        return a - n + 1;
      }
      ++a;
      if (!(a & (a - 1))) return n + 1;
    }
  }

  // Find max a s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from right to left.
  //   Returns -1 if there is no such a.
  template <class F, class... Args>
  int findLeft(int b, F f, Args &&... args) {
    assert(0 <= b); assert(b <= n);
    if ((T().*f)(args...)) return b;
    if (b == 0) return -1;
    b += n;
    for (; ; b >>= 1) if ((b & 1) || b == 2) {
      if ((ts[b - 1].*f)(args...)) {
        for (; b <= n; ) {
          if (!(ts[(b <<= 1) - 1].*f)(args...)) --b;
        }
        return b - n - 1;
      }
      --b;
      if (!(b & (b - 1))) return -1;
    }
  }
};

////////////////////////////////////////////////////////////////////////////////

// T: monoid representing information of an interval.
//   T()  should return the identity.
//   T(S s)  should represent a single element of the array.
//   T::push(T &l, T &r)  should push the lazy update.
//   T::pull(const T &l, const T &r)  should pull two intervals.
template <class T> struct SegmentTreeRange {
  int logN, n;
  vector<T> ts;
  SegmentTreeRange() : logN(0), n(0) {}
  explicit SegmentTreeRange(int n_) {
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
  }
  template <class S> explicit SegmentTreeRange(const vector<S> &ss) {
    const int n_ = ss.size();
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
    for (int i = 0; i < n_; ++i) at(i) = T(ss[i]);
    build();
  }
  T &at(int i) {
    return ts[n + i];
  }
  void build() {
    for (int u = n; --u; ) pull(u);
  }

  inline void push(int u) {
    ts[u].push(ts[u << 1], ts[u << 1 | 1]);
  }
  inline void pull(int u) {
    ts[u].pull(ts[u << 1], ts[u << 1 | 1]);
  }

  // Applies T::f(args...) to [a, b).
  template <class F, class... Args>
  void ch(int a, int b, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return;
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) (ts[aa++].*f)(args...);
      if (bb & 1) (ts[--bb].*f)(args...);
    }
    for (int h = 1; h <= logN; ++h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) pull(aa);
      } else {
        if ((aa << h) != a) pull(aa);
        if ((bb << h) != b) pull(bb);
      }
    }
  }

  // Calculates the product for [a, b).
  T get(int a, int b) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return T();
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    T prodL, prodR, t;
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) { t.pull(prodL, ts[aa++]); prodL = t; }
      if (bb & 1) { t.pull(ts[--bb], prodR); prodR = t; }
    }
    t.pull(prodL, prodR);
    return t;
  }

  // Calculates T::f(args...) of a monoid type for [a, b).
  //   op(-, -)  should calculate the product.
  //   e()  should return the identity.
  template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
  auto
#else
  decltype((std::declval<T>().*F())())
#endif
  get(int a, int b, Op op, E e, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return e();
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    auto prodL = e(), prodR = e();
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) prodL = op(prodL, (ts[aa++].*f)(args...));
      if (bb & 1) prodR = op((ts[--bb].*f)(args...), prodR);
    }
    return op(prodL, prodR);
  }

  // Find min b s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from left to right.
  //   Returns n + 1 if there is no such b.
  template <class F, class... Args>
  int findRight(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a <= n);
    if ((T().*f)(args...)) return a;
    if (a == n) return n + 1;
    a += n;
    for (int h = logN; h; --h) push(a >> h);
    for (; ; a >>= 1) if (a & 1) {
      if ((ts[a].*f)(args...)) {
        for (; a < n; ) {
          push(a);
          if (!(ts[a <<= 1].*f)(args...)) ++a;
        }
        return a - n + 1;
      }
      ++a;
      if (!(a & (a - 1))) return n + 1;
    }
  }

  // Find max a s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from right to left.
  //   Returns -1 if there is no such a.
  template <class F, class... Args>
  int findLeft(int b, F f, Args &&... args) {
    assert(0 <= b); assert(b <= n);
    if ((T().*f)(args...)) return b;
    if (b == 0) return -1;
    b += n;
    for (int h = logN; h; --h) push((b - 1) >> h);
    for (; ; b >>= 1) if ((b & 1) || b == 2) {
      if ((ts[b - 1].*f)(args...)) {
        for (; b <= n; ) {
          push(b - 1);
          if (!(ts[(b <<= 1) - 1].*f)(args...)) --b;
        }
        return b - n - 1;
      }
      --b;
      if (!(b & (b - 1))) return -1;
    }
  }
};

////////////////////////////////////////////////////////////////////////////////

struct NodeSum {
  int sum;
  NodeSum(int sum_ = 0) : sum(sum_) {}
  void pull(const NodeSum &l, const NodeSum &r) {
    sum = l.sum + r.sum;
  }
  bool test(int &tar) {
    if (tar <= sum) return true;
    tar -= sum;
    return false;
  }
};

constexpr int INF = 1001001001;

struct NodeMax {
  int mx;
  int lz;
  NodeMax() : mx(-INF), lz(0) {}
  NodeMax(int val) : mx(val), lz(0) {}
  void push(NodeMax &l, NodeMax &r) {
    if (lz) {
      l.add(lz);
      r.add(lz);
      lz = 0;
    }
  }
  void pull(const NodeMax &l, const NodeMax &r) {
    mx = max(l.mx, r.mx);
  }
  void add(int val) {
    mx += val;
    lz += val;
  }
  // leaf
  void change(int val) {
    mx = val;
  }
};

////////////////////////////////////////////////////////////////////////////////


int N, Q;
vector<int> A;
vector<int> L, R, X;


int segN;
vector<vector<int>> qss, rss;
SegmentTreePoint<NodeSum> above;

vector<vector<int>> addss, remss;
void exists(int q, int r) {
cerr<<"exists "<<q<<" "<<r<<endl;
  addss[q].emplace_back(X[q]);
  remss[r].emplace_back(X[q]);
}

void dfs(int u, int L0, int R0) {
  /*
    above: cover above
    qss[u]: cover exactly
    qqss[u]: cover partially below
  */
  const auto &qs = qss[u];
  auto &rs = rss[u];
if(qs.size()){cerr<<COLOR("33")<<u<<" "<<L0<<" "<<R0<<": "<<qs<<" "<<rs<<"; ";for(int q=0;q<Q;++q)cerr<<above.get(q,q+1).sum<<" ";cerr<<COLOR()<<endl;}
  rs.push_back(Q);
  
  for (const int q : qs) above.change(q, 1);
  
  // start with HP of A[i]
  SegmentTreeRange<NodeMax> seg(R0 - L0);
  for (int i = L0; i < R0; ++i) if (i < N) {
    seg.at(i - L0) = A[i];
  }
  seg.build();
  auto below = [&](int j, int val) -> void {
    seg.ch(L[j] - L0, R[j] - L0, &NodeMax::add, val);
  };
  
  int j0 = 0, j1 = 0;
  for (const int q : qs) {
    for (; j0 < j1 && rs[j0] < q; ++j0) below(j0, +1);
    for (; rs[j1] < q; ++j0, ++j1) {}
    for (; ; ++j1) {
      // extinct before rs[j1] ?
      int hp = seg.ts[1].mx;
// cerr<<"  q = "<<q<<", j1 = "<<j1<<", hp = "<<hp<<endl;
      const int pos = above.findRight(q + 1, &NodeSum::test, hp);
// cerr<<"  pos = "<<pos<<endl;
      if (pos <= rs[j1]) {
        exists(q, pos - 1);
        break;
      }
      if (rs[j1] == Q) {
        exists(q, Q);
        break;
      }
      below(j1, -1);
    }
  }
  
  if (u < segN) {
    const int mid = (L0 + R0) >> 1;
    dfs(u << 1, L0, mid);
    dfs(u << 1 | 1, mid, R0);
  }
  for (const int q : qs) above.change(q, 0);
}

int main() {
  for (; ~scanf("%d%d", &N, &Q); ) {
    A.resize(N);
    for (int i = 0; i < N; ++i) {
      scanf("%d", &A[i]);
    }
    L.resize(Q);
    R.resize(Q);
    X.resize(Q);
    for (int q = 0; q < Q; ++q) {
      scanf("%d%d%d", &L[q], &R[q], &X[q]);
      --L[q];
    }
    
    for (segN = 1; segN < N; segN <<= 1) {}
    qss.assign(segN << 1, {});
    rss.assign(segN << 1, {});
    for (int q = 0; q < Q; ++q) {
      int a, b, c, d;
      a = c = segN + L[q];
      b = d = segN + R[q] - 1;
      for (; a <= b; a >>= 1, b >>= 1, c >>= 1, d >>= 1) {
        if (a != c) rss[c].push_back(q);
        if (b != d) rss[d].push_back(q);
        if (a & 1) qss[a++].push_back(q);
        if (~b & 1) qss[b--].push_back(q);
      }
      for (; c; c >>= 1, d >>= 1) {
        rss[c].push_back(q);
        if (c != d) rss[d].push_back(q);
      }
    }
    above = SegmentTreePoint<NodeSum>(Q);
    addss.assign(Q + 1, {});
    remss.assign(Q + 1, {});
    dfs(1, 0, segN);
    
    const int limX = *max_element(X.begin(), X.end()) + 1;
    vector<int> now(limX, 0);
    int kind = 0;
    for (int q = 0; q < Q; ++q) {
      for (const int x : addss[q]) if (!now[x]++) ++kind;
      for (const int x : remss[q]) if (!--now[x]) --kind;
      printf("%d\n", kind);
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Runtime Error

Test #1:

score: 0
Runtime Error

input:

5000 4999
99 36 47 78 58 58 64 12 42 54 29 56 57 32 99 21 1 6 42 97 82 8 79 92 3 56 19 41 29 59 23 34 76 34 82 20 44 51 60 73 89 65 51 65 15 87 65 70 51 26 40 95 44 62 97 81 43 13 20 81 76 64 47 95 54 56 99 62 91 63 98 58 70 60 47 97 31 74 76 70 10 30 99 33 52 100 14 65 4 6 87 4 8 1 8 87 18 70 76 43...

output:


result:


Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Skipped

Dependency #3:

0%

Subtask #5:

score: 0
Runtime Error

Test #5:

score: 0
Runtime Error

input:

25000 25000
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...

output:


result:


Subtask #6:

score: 0
Skipped

Dependency #4:

0%

Subtask #7:

score: 0
Runtime Error

Test #7:

score: 0
Runtime Error

input:

34999 35000
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 ...

output:


result:


Subtask #8:

score: 0
Skipped

Dependency #6:

0%

Subtask #9:

score: 0
Runtime Error

Test #9:

score: 0
Runtime Error

input:

45000 45000
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ...

output:


result:


Subtask #10:

score: 0
Skipped

Dependency #8:

0%

Subtask #11:

score: 0
Skipped

Dependency #5:

0%

Subtask #12:

score: 0
Skipped

Dependency #11:

0%

Subtask #13:

score: 0
Runtime Error

Test #13:

score: 0
Runtime Error

input:

65000 65000
5 7 8 6 3 6 8 7 2 3 5 10 9 9 4 3 9 1 2 9 1 1 6 10 1 10 5 4 7 1 9 6 6 8 10 5 8 3 2 5 2 3 6 8 7 3 2 3 6 5 1 10 6 2 4 7 8 1 3 3 5 4 2 5 2 5 3 3 6 7 6 9 5 3 10 3 6 2 8 10 9 10 2 5 4 10 3 3 6 3 5 7 141 3 6 3 10 2 7 6 3 5 9 4 10 1 3 9 9 8 2 5 10 1 7 1 8 5 3 3 7 7 9 7 4 1 9 2 2 4 8 6 10 5 7 3 3...

output:


result:


Subtask #14:

score: 0
Skipped

Dependency #12:

0%

Subtask #15:

score: 0
Skipped

Dependency #13:

0%

Subtask #16:

score: 0
Skipped

Dependency #14:

0%

Subtask #17:

score: 0
Skipped

Dependency #16:

0%

Subtask #18:

score: 0
Skipped

Dependency #17:

0%

Subtask #19:

score: 0
Skipped

Dependency #18:

0%

Subtask #20:

score: 0
Skipped

Dependency #19:

0%