QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#399989#3299. Advertisement Matchinghos_lyricRE 1ms3984kbC++1410.1kb2024-04-26 20:42:562024-04-26 20:42:57

Judging History

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

  • [2024-04-26 20:42:57]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:3984kb
  • [2024-04-26 20:42:56]
  • 提交

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::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;
    }
  }
};

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

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

constexpr Int INF = 1001001001001001001LL;

struct NodeMin {
  Int mn;
  Int lz;
  NodeMin() : mn(INF), lz(0) {}
  NodeMin(Int val) : mn(val), lz(0) {}
  void push(NodeMin &l, NodeMin &r) {
    if (lz) {
      l.add(lz);
      r.add(lz);
      lz = 0;
    }
  }
  void pull(const NodeMin &l, const NodeMin &r) {
    mn = min(l.mn, r.mn);
  }
  void add(Int val) {
    mn += val;
    lz += val;
  }
  // leaf
  void change(Int val) {
    mn = val;
  }
};

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


// maintain non-decr. sequence
struct Increasing {
  // values in [0, m)
  int m;
  // value a: position [ls[a], rs[a]]
  vector<int> ls, rs;
  Increasing(int m_, vector<int> as) : m(m_), ls(m, 0), rs(m, -1) {
    sort(as.begin(), as.end());
    for (int i = 0; i < (int)as.size(); ++i) {
      const int a = as[i];
      assert(0 <= a); assert(a < m);
      if (ls[a] <= rs[a]) {
        assert(rs[a] == i - 1);
        rs[a] = i;
      } else {
        ls[a] = rs[a] = i;
      }
    }
  }
  // a -> a+1, where to increase?
  int inc(int a) {
    assert(0 <= a); assert(a + 1 < m);
    assert(ls[a] <= rs[a]);
    const int i = rs[a]--;
    if (ls[a + 1] <= rs[a + 1]) {
      assert(ls[a + 1] == i + 1);
      ls[a + 1] = i;
    } else {
      ls[a + 1] = rs[a + 1] = i;
    }
    return i;
  }
  // a -> a-1, where to increase?
  int dec(int a) {
    assert(0 <= a - 1); assert(a < m);
    const int i = ls[a]++;
    if (ls[a - 1] <= rs[a - 1]) {
      assert(rs[a - 1] == i - 1);
      rs[a - 1] = i;
    } else {
      ls[a - 1] = rs[a - 1] = i;
    }
    return i;
  }
};


/*
  a[0] <= ... <= a[M-1]
  b[0] <= ... <= b[N-1]
  
  mincut
  = \min[0<=m<=M, 0<=n<=N] (m n + \sum a[0, M-m) + \sum b[0, N-n))
  = \min[0<=m<=M] (\sum[0, M-m) + \sum[j] min{m, b[j]})
*/

int M, N;
vector<int> A, B;
int Q;
vector<int> O, C;

int main() {
  for (; ~scanf("%d%d", &M, &N); ) {
    A.resize(M); for (int i = 0; i < M; ++i) scanf("%d", &A[i]);
    B.resize(N); for (int j = 0; j < N; ++j) scanf("%d", &B[j]);
    scanf("%d", &Q);
    O.resize(Q);
    C.resize(Q);
    for (int q = 0; q < Q; ++q) {
      scanf("%d%d", &O[q], &C[q]);
      --C[q];
    }
    
    auto as = A;
    auto bs = B;
    sort(as.begin(), as.end());
    sort(bs.begin(), bs.end());
    Increasing f(*max_element(A.begin(), A.end()) + Q + 1, as);
    
    vector<Int> asSum(M + 1, 0);
    vector<Int> bsSum(N + 1, 0);
    for (int i = 0; i < M; ++i) asSum[i + 1] = asSum[i] + as[i];
    for (int j = 0; j < N; ++j) bsSum[j + 1] = bsSum[j] + bs[j];
    vector<Int> ini(M + 1, 0);
    for (int j = 0, m = 0; m <= M; ++m) {
      for (; j < N && bs[j] < m; ++j) {}
      ini[m] += asSum[M - m];
      ini[m] += bsSum[j];
      ini[m] += (Int)(N - j) * m;
    }
// cerr<<"ini = "<<ini<<endl;
    SegmentTreeRange<NodeMin> seg(ini);
    Int sumA = asSum[M];
    
    for (int q = 0; q < Q; ++q) {
      if (false) {
      } else if (O[q] == 1) {
        const int i = f.inc(A[C[q]]++);
        seg.ch(0, M - i, &NodeMin::add, +1);
        ++sumA;
      } else if (O[q] == 2) {
        const int i = f.dec(A[C[q]]--);
        seg.ch(0, M - i, &NodeMin::add, -1);
        --sumA;
      } else if (O[q] == 3) {
        // min{m, b+1} - min{m, b} = +[m >= b+1]
        int &b = B[C[q]];
        seg.ch(b + 1, M + 1, &NodeMin::add, +1);
        ++b;
      } else if (O[q] == 4) {
        // min{m, b-1} - min{m, b} = -[m >= b]
        int &b = B[C[q]];
        seg.ch(b, M + 1, &NodeMin::add, -1);
        --b;
      } else {
        assert(false);
      }
      const Int mc = seg.ts[1].mn;
// cerr<<"mc = "<<mc<<", sumA = "<<sumA<<endl;
      puts((mc == sumA) ? "1" : "0");
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3968kb

input:

5 5
1 5 2 4 3
3 3 3 3 3
5
4 2
3 5
2 2
1 1
1 4

output:

0
1
1
1
0

result:

ok 5 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3984kb

input:

100 100
13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 1...

output:

1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

ok 100 lines

Test #3:

score: 0
Accepted
time: 0ms
memory: 3632kb

input:

100 100
42 28 42 64 42 29 72 64 72 29 28 72 28 72 29 42 64 42 72 29 64 29 72 28 42 64 72 64 28 42 72 42 29 64 72 64 72 29 72 29 64 42 64 72 29 28 42 64 72 64 72 28 42 64 64 42 64 64 28 28 72 29 28 64 28 64 64 72 64 28 42 29 64 42 64 42 72 64 64 64 28 64 42 72 64 29 64 29 64 64 72 29 29 28 42 72 64 7...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

ok 100 lines

Test #4:

score: 0
Accepted
time: 0ms
memory: 3684kb

input:

100 100
13 40 46 59 64 64 3 34 64 13 46 13 13 46 46 16 64 48 26 13 59 50 16 46 41 5 59 13 64 16 20 43 41 26 14 16 34 64 59 41 73 71 64 50 14 48 71 50 71 26 43 59 5 50 16 71 77 77 59 14 3 41 71 7 41 40 16 13 50 13 64 64 16 59 40 5 26 50 64 59 3 5 40 41 16 5 13 46 40 14 40 34 40 59 46 14 26 41 43 64
2...

output:

1
0
1
1
0
1
1
1
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

ok 100 lines

Test #5:

score: 0
Accepted
time: 0ms
memory: 3724kb

input:

100 100
69 81 86 84 48 31 42 27 14 18 7 8 61 41 97 9 38 88 24 48 52 92 60 28 18 61 51 64 98 9 72 13 35 97 32 8 17 79 54 5 100 1 76 21 11 12 52 5 98 25 61 37 82 4 18 22 96 10 23 68 92 63 40 25 27 67 39 36 44 82 6 31 17 3 7 90 21 80 62 9 73 26 75 57 20 20 86 35 46 45 89 40 18 43 16 68 4 6 89 75
37 1 7...

output:

0
1
0
1
1
1
1
1
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1

result:

ok 100 lines

Test #6:

score: -100
Runtime Error

input:

1000 1000
885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 885 88...

output:


result: