Submission #1271321

#TimeUsernameProblemLanguageResultExecution timeMemory
1271321model_codeExamination 2 (JOI24_examination2)C++20
100 / 100
226 ms58428 KiB
#include <bits/stdc++.h>

using namespace std;

template <typename T>
using vc = vector<T>;

#define all(x) x.begin(), x.end()
#define len(x) int(x.size())
#define eb emplace_back
#define fi first
#define se second
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

struct Dual_SegTree {
  int n, log, size;
  using X = array<bool, 2>;
  vc<X> dat;

  Dual_SegTree(int n) : n(n) {
    log = 1;
    while ((1 << log) < n) ++log;
    size = 1 << log;
    dat.assign(size << 1, {0, 1});
  }
  void flip(int l, int r) { apply(l, r, {1, 0}); }
  void set_true(int l, int r) { apply(l, r, {1, 1}); }
  void set_false(int l, int r) { apply(l, r, {0, 0}); }

  bool get(int p) {
    assert(0 <= p && p < n);
    p += size;
    for (int i = log; i >= 1; i--) push(p >> i);
    return dat[p][0];
  }

  void apply(int l, int r, const X a) {
    assert(0 <= l && l <= r && r <= n);
    l += size, r += size;
    for (int i = log; i >= 1; i--) {
      if (((l >> i) << i) != l) push(l >> i);
      if (((r >> i) << i) != r) push((r - 1) >> i);
    }
    while (l < r) {
      if (l & 1) apply_at(l++, a);
      if (r & 1) apply_at(--r, a);
      l >>= 1, r >>= 1;
    }
  }
  void push(int k) {
    apply_at(2 * k, dat[k]), apply_at(2 * k + 1, dat[k]);
    dat[k] = {0, 1};
  }
  void apply_at(int k, X a) { dat[k] = {a[dat[k][0]], a[dat[k][1]]}; }
};

struct Node {
  int type, l, r, size;
};

int p;
string S;
vc<Node> node;

int new_node(int t, int l, int r) {
  int k = len(node);
  int s = (t == 1 ? 1 : node[l].size + (r == -1 ? 0 : node[r].size));
  node.eb(Node{t, l, r, s});
  return k;
}

int FUNC_1();
int FUNC_2();
int FUNC_3();
int FUNC_4();
int FUNC_5();
int FUNC_6();
int IOI_FUNCTION();

int number() {
  int x = 0;
  assert('1' <= S[p] && S[p] <= '9');
  while ('0' <= S[p] && S[p] <= '9') { x = 10 * x + (S[p++] - '0'); }
  assert(1 <= x && x <= 1'000'000'000);
  return x;
}

int FUNC_1() {
  assert(S[p] == '[');
  ++p;
  int a = number();
  assert(S[p] == ']');
  ++p;
  return new_node(1, a, -1);
}

int FUNC_2() {
  if (S[p] != '(') return FUNC_1();
  assert(S[p] == '(');
  ++p;
  int k = IOI_FUNCTION();
  assert(S[p] == ')');
  ++p;
  return k;
}

int FUNC_3() {
  if (S[p] != '!') return FUNC_2();
  assert(S[p] == '!');
  ++p;
  int r = FUNC_3();
  return new_node(3, r, -1);
}

int FUNC_4() {
  int k = FUNC_3();
  while (p < len(S) && S[p] == '&') {
    ++p;
    int r = FUNC_3();
    k = new_node(4, k, r);
  }
  return k;
}

int FUNC_5() {
  int k = FUNC_4();
  while (p < len(S) && S[p] == '^') {
    ++p;
    int r = FUNC_4();
    k = new_node(5, k, r);
  }
  return k;
}

int FUNC_6() {
  int k = FUNC_5();
  while (p < len(S) && S[p] == '|') {
    ++p;
    int r = FUNC_5();
    k = new_node(6, k, r);
  }
  return k;
}

int IOI_FUNCTION() { return FUNC_6(); }

void solve() {
  int N, Q;
  cin >> N >> Q >> S;
  int root = IOI_FUNCTION();

  // make heavy child left
  for (auto& [t, l, r, s]: node) {
    if (r != -1 && node[l].size < node[r].size) swap(l, r);
  }

  vc<pair<vc<int>, vc<bool>>> ANS(len(node));

  auto dfs = [&](auto& dfs, int v) -> void {
    vc<int> path;
    vc<int> X = {0};
    int p = v;
    while (1) {
      path.eb(p);
      int r = node[p].r;
      if (r != -1) {
        dfs(dfs, r);
        X.insert(X.end(), all(ANS[r].fi));
      }
      if (node[p].type == 1) {
        X.eb(node[p].l);
        break;
      }
      p = node[p].l;
    }

    UNIQUE(X);

    int n = len(X);
    Dual_SegTree seg(n);

    while (len(path)) {
      int v = path.back();
      path.pop_back();
      auto [t, l, r, sz] = node[v];
      if (t == 1) {
        seg.set_true(LB(X, node[v].l), n);
        continue;
      }
      if (t == 3) {
        seg.flip(0, n);
        continue;
      }
      assert(t == 4 || t == 5 || t == 6);
      auto [Y, ans] = ANS[r];
      for (auto& y: Y) y = LB(X, y);
      Y.eb(n);
      for (int i = 0; i < len(Y) - 1; ++i) {
        int a = Y[i], b = Y[i + 1];
        bool k = ans[i];
        if (t == 4 && !k) seg.set_false(a, b);
        if (t == 5 && k) seg.flip(a, b);
        if (t == 6 && k) seg.set_true(a, b);
      }
    }
    vc<bool> ans(n);
    for (int i = 0; i < n; ++i) ans[i] = seg.get(i);
    ANS[v] = {X, ans};
  };

  dfs(dfs, root);

  auto [X, ans] = ANS[root];

  for (int q = 0; q < Q; ++q) {
    int x;
    cin >> x;
    int k = UB(X, x) - 1;
    cout << (ans[k] ? "True" : "False") << "\n";
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  solve();
  return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...