Problem:
G: 式の切り取り
問題
長さ $N$ の数式 $S$ が与えられる。
  数式は、以下の BNF で示される形式になっている。
<expr> ::= <number> | <expr> <op> <expr>
<op> ::= ‘^’ | ‘&’ | ‘|’
<number> は、 $0$ 以上 $2^{31}-1$ 以下の整数を表す。
演算子、’^’  ‘&’  ‘|’  は、それぞれ排他的論理和、論理積、論理和を表す。
  演算子の優先順位は以下の通りである。
高　’^’ > ‘&’ > ‘|’　低
区間 $[i, j]$ が $Q$ 個与えられる。
  $S_i, \dots , S_j$ の計算結果を出力せよ。
なお、数式 $S_i, \dots , S_j$ が上記のBNFで示される形式であることは保証される。また、数式にゼロ詰めされた値が含まれることはない。
制約
$1 \leq N, Q \leq 10^5$
$N = |S| \ \ \ \ \ |S|$ は文字列の長さを表す。
$0 \leq i \leq j < N$
入力形式
入力は以下の形式で与えられる。
$N$
$S$
$Q$
$i_1\ j_1$
$\vdots$
$i_Q\ j_Q$
出力
$S_i, \dots , S_j$ の計算結果を出力せよ。 また、末尾に改行も出力せよ。
サンプル
サンプル入力 1
7
9^2&1|2
4
0 6
0 2
2 6
4 4
サンプル出力 1
3
11
2
1
サンプル入力 2
13
3423&423^1234
3
2 12
5 9
9 12
サンプル出力 2
21
422
1234
サンプル入力 3
7
1234567
3
0 0
0 1
4 6
サンプル出力 3
1
12
567

Submitted solutions:

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll INF = 1e18;

template <typename T>
bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

ll N;
string S;
ll Q;
ll A[105000];
ll B[105000];
ll C[105000];
ll AR[105000];
ll BR[105000];
ll CR[105000];
ll AL[105000];
ll BL[105000];
ll CL[105000];
ll a, b, c;
vector<ll> number;
vector<ll> xorsum;
vector<ll> andsum;
ll nownum = 0;


struct XORSegmentTree {
    ll n;
    vector<ll> node;
    XORSegmentTree(vector<ll> v) {
        int sz = v.size();
        n = 1;
        while(n < sz) n *= 2;
        node.resize(2 * n - 1, 0LL);
        for(int i = 0; i < sz; i++) node[i+n-1] = v[i];
        for(int i = n - 2; i >= 0; i--) node[i] = node[2*i+1]^node[2*i+2];
    }
    ll fold(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) {
        if(r < 0) r = n;
        if(r <= a or b <= l) return 0;
        if(a <= l and r <= b) return node[k];
        ll vl = fold(a, b, 2*k+1, l, (l+r)/2);
        ll vr = fold(a, b, 2*k+2, (l+r)/2, r);
        return vl ^ vr;
    }
};

struct ORSegmentTree {
    ll n;
    vector<ll> node;
    ORSegmentTree(vector<ll> v) {
        int sz = v.size();
        n = 1;
        while(n < sz) n *= 2;
        node.resize(2 * n - 1, 0LL);
        for(int i = 0; i < sz; i++) node[i+n-1] = v[i];
        for(int i = n - 2; i >= 0; i--) node[i] = node[2*i+1] | node[2*i+2];
    }
    ll fold(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) {
        if(r < 0) r = n;
        if(r <= a or b <= l) return 0;
        if(a <= l and r <= b) return node[k];
        ll vl = fold(a, b, 2*k+1, l, (l+r)/2);
        ll vr = fold(a, b, 2*k+2, (l+r)/2, r);
        return vl | vr;
    }
};

struct ANDSegmentTree {
    ll n;
    vector<ll> node;
    ANDSegmentTree(vector<ll> v) {
        int sz = v.size();
        n = 1;
        while(n < sz) n *= 2;
        node.resize(2 * n - 1, (1LL << 32) - 1);
        for(int i = 0; i < sz; i++) node[i+n-1] = v[i];
        for(int i = n - 2; i >= 0; i--) node[i] = node[2*i+1]&node[2*i+2];
    }
    ll fold(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) {
        if(r < 0) r = n;
        if(r <= a or b <= l) return (1LL << 32) - 1;
        if(a <= l and r <= b) return node[k];
        ll vl = fold(a, b, 2*k+1, l, (l+r)/2);
        ll vr = fold(a, b, 2*k+2, (l+r)/2, r);
        return vl & vr;
    }
};

XORSegmentTree XORseg({});
ANDSegmentTree ANDseg({});
ORSegmentTree ORseg({});


bool IsNumber(char c) {
    return '0' <= c and c <= '9';
}
ll f1(ll l, ll r);
ll f2(ll l, ll r);
ll f3(ll l, ll r);
ll f4(ll l, ll r);

ll ORSUM(ll l, ll r) {
    ll ret = 0;
    for(int i = l; i < r; i++) ret |= andsum[i];
    return ret;
}

ll ANDSUM(ll l, ll r) {
    ll ret = (1LL << 32) - 1;
    for(int i = l; i < r; i++) ret &= xorsum[i];
    return ret;
}

ll XORSUM(ll l, ll r) {
    ll ret = 0;
    for(int i = l; i < r; i++) ret ^= number[i];
    return ret;
}

ll f1(ll l, ll r) {
    //cerr << "f1: " << l << " " << r << endl;
    ll lidx = A[l];
    ll ridx = A[r];
    if(lidx == ridx) {
        return f2(l, r);
    }
    ll ret = f2(l, AR[lidx]);
    //ret |= ORSUM(lidx + 1, ridx - 1);
    ret |= ORseg.fold(lidx + 1, ridx);
    ret |= f2(AL[ridx], r);
    return ret;
}

ll f2(ll l, ll r) {
    //cerr << "f2: " << l << " " << r << endl;
    assert(A[l] == A[r]);
    ll lidx = B[l];
    ll ridx = B[r];
    if(lidx == ridx) {
        return f3(l, r);
    }
    ll ret = f3(l, BR[lidx]);
    //ret &= ANDSUM(lidx + 1, ridx - 1);
    ret &= ANDseg.fold(lidx + 1, ridx);
    ret &= f3(BL[ridx], r);
    return ret;
}

ll f3(ll l, ll r) {
    //cerr << "f3: " << l << " " << r << endl;
    assert(A[l] == A[r]);
    assert(B[l] == B[r]);
    ll lidx = C[l];
    ll ridx = C[r];
    if(lidx == ridx) {
        return f4(l, r);
    }
    ll ret = f4(l, CR[lidx]);
    ret ^= XORseg.fold(lidx + 1, ridx);
    //ret ^= XORSUM(lidx + 1, ridx - 1);
    ret ^= f4(CL[ridx], r);
    return ret;
}

ll f4(ll l, ll r) {
    //cerr << "f4: " << l << " " << r << endl;
    assert(A[l] == A[r]);
    assert(B[l] == B[r]);
    assert(C[l] == C[r]);
    ll ret = 0;
    for(int i = l; i <= r; i++) {
        assert(IsNumber(S[i]));
        ret *= 10;
        ret += (S[i] - '0');
    }
    //cerr << "A" << ret << endl;
    return ret;
}

void print(vector<ll> v) {
    cerr << "{";
    for(int i = 0; i < v.size(); i++) {
        if(i != 0) cerr << ", ";
        cerr << v[i];
    }
    cerr << "}" << endl;
}

int main() {
    cin >> N >> S;
    for(int i = 0; i < N; i++) {
        AL[i] = INF;
        BL[i] = INF;
        CL[i] = INF;
    }
    cin >> Q;
    for(int i = 0; i < N; i++) {
        A[i] = a;
        B[i] = b;
        C[i] = c;
        if(IsNumber(S[i])) {
            nownum *= 10;
            nownum += (S[i] - '0');
            continue;
        }
        if(S[i] == '^') {
            c++;
        }
        if(S[i] == '&') {
            c++;
            b++;
        }
        if(S[i] == '|') {
            c++;
            b++;
            a++;
        }
        number.push_back(nownum);
        nownum = 0;
    }
    number.push_back(nownum);
    for(ll i = 0; i < N; i++) {
        if(!IsNumber(S[i])) continue;
        chmin(AL[A[i]], i);
        chmin(BL[B[i]], i);
        chmin(CL[C[i]], i);
        chmax(AR[A[i]], i);
        chmax(BR[B[i]], i);
        chmax(CR[C[i]], i);
    }
    /*
    for(int i = 0; i < N; i++) {
        cerr << A[i] << " ";
    }
    cerr << endl;
    for(int i = 0; i < N; i++) {
        cerr << B[i] << " ";
    }
    cerr << endl;
    for(int i = 0; i < N; i++) {
        cerr << C[i] << " ";
    }
    cerr << endl;
    */
    assert(number.size() == C[N-1] + 1);
    xorsum.resize(B[N-1] + 1, 0LL);
    for(int i = 0; i < number.size(); i++) {
        ll idx = CL[i];
        xorsum[B[idx]] ^= number[i];
    }
    andsum.resize(A[N-1] + 1, (1LL << 32) - 1);
    for(int i = 0; i < xorsum.size(); i++) {
        ll idx = BL[i];
        andsum[A[idx]] &= xorsum[i];
    }
    XORseg = XORSegmentTree(number);
    ANDseg = ANDSegmentTree(xorsum);
    ORseg = ORSegmentTree(andsum);
    //print(number);
    //print(xorsum);
    //print(andsum);
    for(int q = 0; q < Q; q++) {
        ll l, r;
        cin >> l >> r;
        cout << f1(l, r) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 10892
final_rank: 6

code_snippet: #include <bits/stdc++.h>

#define all(c) begin(c), end(c)
#define rep(i, a, b) for (int i = a; i < int(b); ++i)
#define sz(c) int(size(c))

using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;

struct segtree {
  int n;
  vi t;
  function<int(int, int)> op;
  int e;

  void build(const vi& v) {
    n = sz(v);
    t.resize(2 * n, e);
    copy(all(v), begin(t) + n);
    for (int i = n; i-- > 1;) t[i] = op(t[2 * i], t[2 * i + 1]);
  }
  int fold(int l, int r) {
    int res = e;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1) res = op(res, t[l++]);
      if (r & 1) res = op(res, t[--r]);
    }
    return res;
  }
};

int n;
string s;

struct node {
  int type;
  vector<node*> ch;
  segtree seg;
  vi pos;
  node(int _type, int l, int r) : type(_type) {
    if (type == 0) seg.op = bit_or<int>{}, seg.e = 0;
    if (type == 1) seg.op = bit_and<int>{}, seg.e = -1;
    if (type == 2) seg.op = bit_xor<int>{}, seg.e = 0;
    vi v;
    if (type != 3) {
      int last = l;
      pos.push_back(l - 1);
      rep(i, l, r + 1) {
        auto p = string("|&^").find(s[i]);
        if (i == r or (p != string::npos and int(p) <= type)) {
          ch.push_back(new node(type + 1, last, i));
          v.push_back(ch.back()->query(last, i));
          last = i + 1;
          pos.push_back(i);
        }
      }
    }
    seg.build(v);
  }
  int query(int l, int r) {
    if (type == 3) {
      return stoi(s.substr(l, r - l));
    } else {
      int a = upper_bound(all(pos), l) - begin(pos) - 1;
      int b = upper_bound(all(pos), r - 1) - begin(pos) - 1;
      int res{};
      if (a == b) {
        res = ch[a]->query(l, r);
      } else {
        res = ch[a]->query(l, pos[a + 1]);
        res = seg.op(res, seg.fold(a + 1, b));
        res = seg.op(res, ch[b]->query(pos[b] + 1, r));
      }
      return res;
    }
  }
};

int main() {
  cin >> n >> s;
  auto t = new node(0, 0, n);
  int q;
  cin >> q;
  while (q--) {
    int l, r;
    cin >> l >> r;
    ++r;
    cout << t->query(l, r) << '\n';
  }
}
accuracy: 1
time_ms: 130
memory_kb: 6668
final_rank: 5

code_snippet: #include <cstdio>
#include <cstdint>
#include <cstddef>
#include <cassert>
#include <cctype>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <limits>
#include <string>

constexpr intmax_t  operator ""_jd(unsigned long long n) { return static_cast<intmax_t>(n); }
constexpr uintmax_t operator ""_ju(unsigned long long n) { return static_cast<uintmax_t>(n); }
constexpr size_t    operator ""_zu(unsigned long long n) { return static_cast<size_t>(n); }
constexpr ptrdiff_t operator ""_td(unsigned long long n) { return static_cast<ptrdiff_t>(n); }

template <
  typename Monoid,
  typename Container = std::vector<typename Monoid::first_type>
>
class basic_segment_tree {
public:
  using size_type = size_t;
  using first_type = typename Monoid::first_type;
  using second_type = typename Monoid::second_type;
  using value_type = first_type;
  using binary_operation = typename Monoid::binary_operation;
  using external_binary_operation = typename Monoid::external_binary_operation;
  using container = Container;

private:
  size_type M_base_size;
  binary_operation M_op1;
  external_binary_operation M_op2;
  container M_c;

  template <typename Predicate>
  size_type M_search_root(Predicate pred, value_type& x) {
    size_type n = M_base_size;
    size_type l = n;
    size_type r = n+n;
    size_type v = r;
    std::vector<size_type> rs;
    x = M_op1.identity;
    while (l < r) {
      if (l & 1) {
        if (!pred(M_op1(x, M_c[l]))) return l;
        x = M_op1(x, M_c[l++]);
      }
      if (r & 1) rs.push_back(--r);
      l >>= 1;
      r >>= 1;
    }
    while (!rs.empty()) {
      size_type r = rs.back();
      rs.pop_back();
      if (!pred(M_op1(x, M_c[r]))) return r;
      x = M_op1(x, M_c[r]);
    }
    return v;
  }

  template <typename Predicate>
  size_type M_search_leaf(Predicate pred, size_type v, value_type& x) {
    size_type n = M_base_size;
    while (v < n) {
      size_type c = v << 1;
      if (pred(M_op1(x, M_c[c]))) {
        x = M_op1(x, M_c[c]);
        c |= 1;
      }
      v = c;
    }
    return v - n;
  }

public:
  basic_segment_tree() = default;
  basic_segment_tree(basic_segment_tree const&) = default;
  basic_segment_tree(basic_segment_tree&&) = default;

  basic_segment_tree(size_type n, first_type const& x = binary_operation().identity):
    M_base_size(n),
    M_op1(binary_operation()),
    M_op2(external_binary_operation()),
    M_c(n+n, x)
  {
    for (size_type i = n; i--;)
      M_c[i] = M_op1(M_c[i<<1|0], M_c[i<<1|1]);
  }

  template <typename InputIt>
  basic_segment_tree(InputIt first, InputIt last):
    M_base_size(std::distance(first, last)),
    M_op1(binary_operation()),
    M_op2(external_binary_operation()),
    M_c(M_base_size*2)
  {
    for (size_type i = M_base_size; first != last; ++i)
      M_c[i] = *first++;
    for (size_type i = M_base_size; i--;)
      M_c[i] = M_op1(M_c[i<<1|0], M_c[i<<1|1]);
  }

  basic_segment_tree& operator =(basic_segment_tree const&) = default;
  basic_segment_tree& operator =(basic_segment_tree&&) = default;

  void modify(size_type i, second_type const& x) {
    i += M_base_size;
    M_c[i] = M_op2(M_c[i], x);
    while (i > 1) {
      i >>= 1;
      M_c[i] = M_op1(M_c[i<<1|0], M_c[i<<1|1]);
    }
  }

  first_type accumulate(size_type l, size_type r) const {
    first_type resl = M_op1.identity;
    first_type resr = resl;
    l += M_base_size;
    r += M_base_size;
    while (l < r) {
      if (l & 1) resl = M_op1(resl, M_c[l++]);
      if (r & 1) resr = M_op1(M_c[--r], resr);
      l >>= 1;
      r >>= 1;
    }
    return M_op1(resl, resr);
  }

  template <typename Predicate>
  size_type bound(Predicate pred) {
    value_type x;
    size_type root = M_search_root(pred, x);
    return M_search_leaf(pred, root, x);
  }

  first_type operator [](size_t i) const { return M_c[i+M_base_size]; }
};

template <typename Tp>
struct range_xor_single_noop {
  using first_type = Tp;
  using second_type = Tp;
  struct binary_operation {
    first_type identity{0};
    first_type operator ()(first_type const& x, first_type const& y) const {
      return x ^ y;
    }
  };
  struct external_binary_operation {
    first_type operator ()(first_type const& x, second_type const&) const { return x; }
  };
};
template <typename Tp>
struct range_and_single_noop {
  using first_type = Tp;
  using second_type = Tp;
  struct binary_operation {
    first_type identity = ~first_type{0};
    first_type operator ()(first_type const& x, first_type const& y) const {
      return x & y;
    }
  };
  struct external_binary_operation {
    first_type operator ()(first_type const& x, second_type const&) const { return x; }
  };
};
template <typename Tp>
struct range_or_single_noop {
  using first_type = Tp;
  using second_type = Tp;
  struct binary_operation {
    first_type identity{0};
    first_type operator ()(first_type const& x, first_type const& y) const {
      return x | y;
    }
  };
  struct external_binary_operation {
    first_type operator ()(first_type const& x, second_type const&) const { return x; }
  };
};

using tsurai_type = unsigned;

tsurai_type nya(tsurai_type x, tsurai_type y, size_t p) {
  if (p == 0) return x | y;
  if (p == 1) return x & y;
  if (p == 2) return x ^ y;
  assert(false);
}

tsurai_type tsurai(std::string const& s, size_t l, size_t r,
                   std::vector<size_t> const& b0,
                   std::vector<size_t> const& b1,
                   std::vector<size_t> const& b2,
                   std::vector<size_t> const& e0,
                   std::vector<size_t> const& e1,
                   std::vector<size_t> const& e2,
                   std::vector<size_t> const& d0,
                   std::vector<size_t> const& d1,
                   std::vector<size_t> const& d2,
                   basic_segment_tree<range_or_single_noop<tsurai_type>> const& s0,
                   basic_segment_tree<range_and_single_noop<tsurai_type>> const& s1,
                   basic_segment_tree<range_xor_single_noop<tsurai_type>> const& s2,
                   size_t preced) {

  if (!isdigit(s[l])) ++l;
  if (l >= s.length()) return 0;
  if (preced == 3) {
    tsurai_type x = 0;
    for (size_t i = l; i < r && isdigit(s[i]); ++i) x = x*10 + s[i]-'0';
    return x;
  }

  auto const& b = ((preced == 0)? b0 : (preced == 1)? b1:b2);
  auto const& e = ((preced == 0)? e0 : (preced == 1)? e1:e2);
  auto const& d = ((preced == 0)? d0 : (preced == 1)? d1:d2);

  size_t ll = b[l];
  size_t rr = e[r];
  if (ll == rr) {
    tsurai_type xl = tsurai(s, l, ll, b0, b1, b2, e0, e1, e2, d0, d1, d2, s0, s1, s2, preced+1);
    tsurai_type xr = tsurai(s, rr, r, b0, b1, b2, e0, e1, e2, d0, d1, d2, s0, s1, s2, preced+1);
    if (!(l < ll)) return xr;
    if (!(rr < r)) return xl;
    return nya(xl, xr, preced);
  }
  if (ll > rr) {
    return tsurai(s, l, r, b0, b1, b2, e0, e1, e2, d0, d1, d2, s0, s1, s2, preced+1);
  }

  tsurai_type x;
  if (preced == 0) {
    x = s0.accumulate(d[ll], d[rr]);
  } else if (preced == 1) {
    x = s1.accumulate(d[ll], d[rr]);
  } else if (preced == 2) {
    x = s2.accumulate(d[ll], d[rr]);
  }

  if (l < ll) {
    tsurai_type y = tsurai(s, l, ll, b0, b1, b2, e0, e1, e2, d0, d1, d2, s0, s1, s2, preced+1);
    x = nya(x, y, preced);
  }
  if (rr < r) {
    tsurai_type y = tsurai(s, rr, r, b0, b1, b2, e0, e1, e2, d0, d1, d2, s0, s1, s2, preced+1);
    x = nya(x, y, preced);
  }
  return x;
}

std::vector<std::string> const ops = {"|", "&", "^"};
unsigned parse(std::string const& s, size_t& i, size_t preced = 0) {
  if (preced == ops.size()) {
    unsigned res = s[i]-'0';
    while (isdigit(s[++i])) res = res*10+s[i]-'0';
    return res;
  }

  unsigned res = parse(s, i, preced+1);
  while (i < s.length()) {
    char op = s[i];
    if (!std::count(ops[preced].begin(), ops[preced].end(), op)) break;
    unsigned tmp = parse(s, ++i, preced+1);
    if (op == '|') res |= tmp;
    if (op == '&') res &= tmp;
    if (op == '^') res ^= tmp;
  }
  return res;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  char buf[131072];
  scanf("%s", buf);
  std::string s = buf;

  std::vector<tsurai_type> num0, num1, num2;
  tsurai_type cur = 0;
  std::vector<size_t> delim{0};
  for (size_t i = 0; i <= n; ++i) {
    if (isdigit(s[i])) {
      cur = cur*10+s[i]-'0';
    } else {
      num2.push_back(cur);
      cur = 0;
      delim.push_back(i);
    }
  }

  // begin, end
  std::vector<size_t> b0(n+1, n), e0(n+1, 0);  // '|'
  std::vector<size_t> b1(n+1, n), e1(n+1, 0);  // '&'
  std::vector<size_t> b2(n+1, n), e2(n+1, 0);  // '^'
  b0[0] = b1[0] = b2[0] = 0;
  e0[n] = e1[n] = e2[n] = n;

  // index, de-index
  std::vector<size_t> i0{0}, i1{0}, i2{0};
  std::vector<size_t> d0(n+1), d1(n+1), d2(n+1);
  for (size_t i = 0; i < n; ++i) {
    if (s[i] == '^') {
      b2[i+1] = e2[i] = i;
      i2.push_back(i);
    } else if (s[i] == '&') { 
      b2[i+1] = e2[i] = i;
      b1[i+1] = e1[i] = i;
      i2.push_back(i);
      i1.push_back(i);
    } else if (s[i] == '|') {
      b2[i+1] = e2[i] = i;
      b1[i+1] = e1[i] = i;
      b0[i+1] = e0[i] = i;
      i2.push_back(i);
      i1.push_back(i);
      i0.push_back(i);
    }
  }
  i2.push_back(n);
  i1.push_back(n);
  i0.push_back(n);

  for (size_t i = 0; i < i0.size(); ++i) d0[i0[i]] = i;
  for (size_t i = 0; i < i1.size(); ++i) d1[i1[i]] = i;
  for (size_t i = 0; i < i2.size(); ++i) d2[i2[i]] = i;

  for (size_t i = n+1; i-- > 1;) {
    b0[i-1] = std::min(b0[i-1], b0[i]);
    b1[i-1] = std::min(b1[i-1], b1[i]);
    b2[i-1] = std::min(b2[i-1], b2[i]);
  }
  for (size_t i = 1; i <= n; ++i) {
    e0[i] = std::max(e0[i-1], e0[i]);
    e1[i] = std::max(e1[i-1], e1[i]);
    e2[i] = std::max(e2[i-1], e2[i]);
  }

  basic_segment_tree<range_xor_single_noop<tsurai_type>> s2(num2.begin(), num2.end());

  for (size_t i = 1; i < i1.size(); ++i)
    num1.push_back(s2.accumulate(d2[i1[i-1]], d2[i1[i]]));

  basic_segment_tree<range_and_single_noop<tsurai_type>> s1(num1.begin(), num1.end());

  for (size_t i = 1; i < i0.size(); ++i)
    num0.push_back(s1.accumulate(d1[i0[i-1]], d1[i0[i]]));

  basic_segment_tree<range_or_single_noop<tsurai_type>> s0(num0.begin(), num0.end());

  size_t q;
  scanf("%zu", &q);

  for (size_t i = 0; i < q; ++i) {
    size_t l, r;
    scanf("%zu %zu", &l, &r);
    ++r;

    unsigned got = tsurai(s, l, r, b0, b1, b2, e0, e1, e2, d0, d1, d2, s0, s1, s2, 0);
    printf("%u\n", got);
  }
}
accuracy: 1
time_ms: 40
memory_kb: 9352
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define sar(a,n) cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl
#define svec(v) cout<<#v<<":";rep(pachico,v.size())cout<<" "<<v[pachico];cout<<endl
#define svecp(v) cout<<#v<<":";each(pachico,v)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl
#define sset(s) cout<<#s<<":";each(pachico,s)cout<<" "<<pachico;cout<<endl
#define smap(m) cout<<#m<<":";each(pachico,m)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

const int MAX_N = 100005;

#define getchar getchar_unlocked
#define putchar putchar_unlocked

inline int in() {
    int n, c;
    while ((c = getchar()) < '0') if (c == EOF) return -1;
    n = c - '0';
    while ((c = getchar()) >= '0') n = n * 10 + c - '0';
    return n;
}

inline void out(int n) {
    int res[11], i = 0;
    do { res[i++] = n % 10, n /= 10; } while (n);
    while (i) putchar(res[--i] + '0');
    putchar('\n');
}

char s[MAX_N];

template<typename T, int NUM> class SyntaxRangeParser {
private:
    class segtree {
    private:
        int opr, size;
        const SyntaxRangeParser* obj;
        vector<T> val;
    public:
        void init(const int opr_, const SyntaxRangeParser* obj_){
            obj = obj_, opr = opr_;
            size = 1;
            while(size < obj->n){
                size *= 2;
            }
            val.resize(2 * size, obj->ie[opr]);
        }
        void update(int k, const T a) {
        	val[k+=obj->n] = a;
        	while(k >>= 1){
        		val[k] = obj->func[opr](val[2 * k], val[2 * k + 1]);
        	}
        }
        T query(int a, int b) {
            T res1 = obj->ie[opr], res2 = obj->ie[opr];
            a += obj->n, b += obj->n;
            while(a != b){
                if(a % 2) res1 = obj->func[opr](res1, val[a++]);
                if(b % 2) res2 = obj->func[opr](res2, val[--b]);
                a >>= 1, b >>= 1;
            }
            return obj->func[opr](res1, res2);
        }
    };
    using pti = pair<T, int>;
    int n;
    T ie[NUM];
    map<char, int> optoi;
    function<T(T, T)> func[NUM];
    vector<int> opr_id[NUM], st[NUM - 1], ed[NUM - 1], num_id;
    int opr_cnt[NUM], num_cnt;
    segtree sg[NUM];
    pti factor(const int l, const int r) {
        num_cnt++;
        T res = 0;
        for(int i = l; i < r; i++){
            res = res * 10 + s[i] - '0';
            num_id[i] = num_cnt;
        }
        return make_pair(res, num_cnt);
    }
    pti term(const int opr, const int l, const int r) {
        if(opr < 0) return factor(l, r);
        opr_cnt[opr]++;
        int pos = l;
        bool flag = true;
        T res = ie[opr];
        for(int i = l; i < r; i++){
            if(optoi[s[i]] == opr + 1){
                pti p = term(opr - 1, pos, i);
                pos = i + 1;
                sg[opr].update(p.second, p.first);
                res = func[opr](res, p.first);
                opr_id[opr][p.second] = opr_cnt[opr];
                if(flag) flag = false, st[opr][opr_cnt[opr]] = p.second;
            }
        }
        pti p = term(opr - 1, pos, r);
        sg[opr].update(p.second, p.first);
        res = func[opr](res, p.first);
        opr_id[opr][p.second] = opr_cnt[opr];
        if(flag) st[opr][opr_cnt[opr]] = p.second;
        ed[opr][opr_cnt[opr]] = p.second + 1;
        return make_pair(res, opr_cnt[opr]);
    }
    pti expr(const int l, const int r) {
        opr_cnt[NUM - 1]++;
        int pos = l;
        T res = ie[NUM - 1];
        for(int i = l; i < r; i++){
            if(optoi[s[i]] == NUM){
                pti p = term(NUM - 2, pos, i);
                pos = i + 1;
                sg[NUM - 1].update(p.second, p.first);
                res = func[NUM - 1](res, p.first);
                opr_id[NUM - 1][p.second] = opr_cnt[NUM - 1];
            }
        }
        pti p = term(NUM - 2, pos, r);
        sg[NUM - 1].update(p.second, p.first);
        res = func[NUM - 1](res, p.first);
        opr_id[NUM - 1][p.second] = opr_cnt[NUM - 1];
        return make_pair(res, opr_cnt[NUM - 1]);
    }
    T number(const int l, const int r){
        T res = 0;
        int pos = l;
        while(pos < r && isdigit(s[pos])){
            res = res * 10 + s[pos++] - '0';
        }
        return res;
    }
    T number_rev(const int l, const int r){
        T res = 0, dig = 1;
        int pos = r-1;
        while(l <= pos && isdigit(s[pos])){
            res += (s[pos--] - '0') * dig, dig *= 10;
        }
        return res;
    }
    void init(){
        func[0] = [&](T x, T y){ return x ^ y; }, optoi['^'] = 1, ie[0] = 0;
        func[1] = [&](T x, T y){ return x & y; }, optoi['&'] = 2, ie[1] = numeric_limits<T>::max();
        func[2] = [&](T x, T y){ return x | y; }, optoi['|'] = 3, ie[2] = 0;
    }
public:
    SyntaxRangeParser(int n_) : n(n_), num_id(n), opr_cnt{}, num_cnt(0){
        rep(i, NUM) sg[i].init(i, this), opr_id[i].resize(n);
        rep(i, NUM - 1) st[i].resize(n), ed[i].resize(n);
        init();
        expr(0, n);
    }
    T query(const int l, const int r) {
        T lnum = number(l, n), rnum = number_rev(0, r);
        int lpre = num_id[l], rpre = num_id[r - 1];
        if(lpre == rpre) return number(l, r);
        for(int i = 0; i < NUM; i++){
            int lnow = opr_id[i][lpre], rnow = opr_id[i][rpre];
            if(lnow == rnow) return func[i](func[i](lnum, sg[i].query(lpre + 1, rpre)), rnum);
            if(i == NUM - 1) break;
            lnum = func[i](lnum, sg[i].query(lpre + 1, ed[i][lnow]));
            rnum = func[i](sg[i].query(st[i][rnow], rpre), rnum);
            lpre = lnow, rpre = rnow;
        }
        return -1;
    }
};

int main()
{
    int n = in();
    scanf("%s",s);
    SyntaxRangeParser<int, 3> srp(n);
    int q = in();
    rep(i,q){
        int l = in(),r = in();
        ++r;
        out(srp.query(l, r));
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 8800
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define sar(a,n) cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl
#define svec(v) cout<<#v<<":";rep(pachico,v.size())cout<<" "<<v[pachico];cout<<endl
#define svecp(v) cout<<#v<<":";each(pachico,v)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl
#define sset(s) cout<<#s<<":";each(pachico,s)cout<<" "<<pachico;cout<<endl
#define smap(m) cout<<#m<<":";each(pachico,m)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

const int MAX_N = 100005;

template<typename T, int NUM> class SyntaxRangeParser {
private:
    class segtree {
    private:
        int opr, size;
        const SyntaxRangeParser* obj;
        vector<T> val;
    public:
        void init(const int opr_, const SyntaxRangeParser* obj_){
            obj = obj_, opr = opr_;
            size = 1;
            while(size < obj->n){
                size *= 2;
            }
            val.resize(2 * size, obj->ie[opr]);
        }
        void update(int k, const T a) {
        	val[k+=obj->n] = a;
        	while(k >>= 1){
        		val[k] = obj->func[opr](val[2 * k], val[2 * k + 1]);
        	}
        }
        T query(int a, int b) {
            T res1 = obj->ie[opr], res2 = obj->ie[opr];
            a += obj->n, b += obj->n;
            while(a != b){
                if(a % 2) res1 = obj->func[opr](res1, val[a++]);
                if(b % 2) res2 = obj->func[opr](res2, val[--b]);
                a >>= 1, b >>= 1;
            }
            return obj->func[opr](res1, res2);
        }
    };
    using pti = pair<T, int>;
    string s;
    int n;
    T ie[NUM];
    map<char, int> optoi;
    function<T(T, T)> func[NUM];
    vector<int> opr_id[NUM], st[NUM - 1], ed[NUM - 1], num_id;
    int opr_cnt[NUM], num_cnt;
    segtree sg[NUM];
    pti factor(const int l, const int r) {
        num_cnt++;
        T res = 0;
        for(int i = l; i < r; i++){
            res = res * 10 + s[i] - '0';
            num_id[i] = num_cnt;
        }
        return make_pair(res, num_cnt);
    }
    pti term(const int opr, const int l, const int r) {
        if(opr < 0) return factor(l, r);
        opr_cnt[opr]++;
        int pos = l;
        bool flag = true;
        T res = ie[opr];
        for(int i = l; i < r; i++){
            if(optoi[s[i]] == opr + 1){
                pti p = term(opr - 1, pos, i);
                pos = i + 1;
                sg[opr].update(p.second, p.first);
                res = func[opr](res, p.first);
                opr_id[opr][p.second] = opr_cnt[opr];
                if(flag) flag = false, st[opr][opr_cnt[opr]] = p.second;
            }
        }
        pti p = term(opr - 1, pos, r);
        sg[opr].update(p.second, p.first);
        res = func[opr](res, p.first);
        opr_id[opr][p.second] = opr_cnt[opr];
        if(flag) st[opr][opr_cnt[opr]] = p.second;
        ed[opr][opr_cnt[opr]] = p.second + 1;
        return make_pair(res, opr_cnt[opr]);
    }
    pti expr(const int l, const int r) {
        opr_cnt[NUM - 1]++;
        int pos = l;
        T res = ie[NUM - 1];
        for(int i = l; i < r; i++){
            if(optoi[s[i]] == NUM){
                pti p = term(NUM - 2, pos, i);
                pos = i + 1;
                sg[NUM - 1].update(p.second, p.first);
                res = func[NUM - 1](res, p.first);
                opr_id[NUM - 1][p.second] = opr_cnt[NUM - 1];
            }
        }
        pti p = term(NUM - 2, pos, r);
        sg[NUM - 1].update(p.second, p.first);
        res = func[NUM - 1](res, p.first);
        opr_id[NUM - 1][p.second] = opr_cnt[NUM - 1];
        return make_pair(res, opr_cnt[NUM - 1]);
    }
    T number(const int l, const int r){
        T res = 0;
        int pos = l;
        while(pos < r && isdigit(s[pos])){
            res = res * 10 + s[pos++] - '0';
        }
        return res;
    }
    T number_rev(const int l, const int r){
        T res = 0, dig = 1;
        int pos = r-1;
        while(l <= pos && isdigit(s[pos])){
            res += (s[pos--] - '0') * dig, dig *= 10;
        }
        return res;
    }
    void init(){
        func[0] = [&](T x, T y){ return x ^ y; }, optoi['^'] = 1, ie[0] = 0;
        func[1] = [&](T x, T y){ return x & y; }, optoi['&'] = 2, ie[1] = numeric_limits<T>::max();
        func[2] = [&](T x, T y){ return x | y; }, optoi['|'] = 3, ie[2] = 0;
    }
public:
    SyntaxRangeParser(string& s_) : s(s_), n(len(s_)), num_id(n), opr_cnt{}, num_cnt(0){
        rep(i, NUM) sg[i].init(i, this), opr_id[i].resize(n);
        rep(i, NUM - 1) st[i].resize(n), ed[i].resize(n);
        init();
        expr(0, n);
    }
    T query(const int l, const int r) {
        T lnum = number(l, n), rnum = number_rev(0, r);
        int lpre = num_id[l], rpre = num_id[r - 1];
        if(lpre == rpre) return number(l, r);
        for(int i = 0; i < NUM; i++){
            int lnow = opr_id[i][lpre], rnow = opr_id[i][rpre];
            if(lnow == rnow) return func[i](func[i](lnum, sg[i].query(lpre + 1, rpre)), rnum);
            if(i == NUM - 1) break;
            lnum = func[i](lnum, sg[i].query(lpre + 1, ed[i][lnow]));
            rnum = func[i](sg[i].query(st[i][rnow], rpre), rnum);
            lpre = lnow, rpre = rnow;
        }
        return -1;
    }
};

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    string s;
    cin >> s;
    SyntaxRangeParser<int, 3> srp(s);
    int q;
    cin >> q;
    rep(i,q){
        int l,r;
        cin >> l >> r;
        ++r;
        cout << srp.query(l, r) << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 8884
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
#define def 0
template<class V, int NV> struct SegTreeXor { //[l,r)
    V comp(V& l, V& r) { return l ^ r; };

    vector<V> val; SegTreeXor() { val = vector<V>(NV * 2, def); }
    V get(int x, int y, int l = 0, int r = NV, int k = 1) {
        if (r <= x || y <= l)return def; if (x <= l && r <= y)return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); 
        auto b = get(x, y, (l + r) / 2, r, k * 2 + 1);
        return comp(a, b);
    }
    void update(int i, V v) {
        i += NV; val[i] = v;
        while (i>1) i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]);
    }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
template<class V, int NV> struct SegTreeAnd { //[l,r)
    V comp(V& l, V& r) { return l & r; };

    vector<V> val; SegTreeAnd() { val = vector<V>(NV * 2, def); }
    V get(int x, int y, int l = 0, int r = NV, int k = 1) {
        if (r <= x || y <= l) return INT_MAX; if (x <= l && r <= y)return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2);
        auto b = get(x, y, (l + r) / 2, r, k * 2 + 1);
        return comp(a, b);
    }
    void update(int i, V v) {
        i += NV; val[i] = v;
        while (i>1) i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]);
    }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
template<class V, int NV> struct SegTreeOr { //[l,r)
    V comp(V& l, V& r) { return l | r; };

    vector<V> val; SegTreeOr() { val = vector<V>(NV * 2, def); }
    V get(int x, int y, int l = 0, int r = NV, int k = 1) {
        if (r <= x || y <= l)return def; if (x <= l && r <= y)return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2);
        auto b = get(x, y, (l + r) / 2, r, k * 2 + 1);
        return comp(a, b);
    }
    void update(int i, V v) {
        i += NV; val[i] = v;
        while (i>1) i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]);
    }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/




int N; string S; int Q;
SegTreeXor<int, 1 << 17> stxor;
SegTreeAnd<int, 1 << 17> stand;
SegTreeOr<int, 1 << 17> stor;
int get_or_id[101010];
int get_and_id[101010];
int get_xor_id[101010];
int get_number_id[101010];
int start_xor[101010], end_xor[101010];
int start_and[101010], end_and[101010];
//---------------------------------------------------------------------------------------------------
pair<int,int> dfs_number(int L, int R) {
    static int number_id = 0;
    number_id++;

    int res = 0;
    rep(i, L, R + 1) {
        res = res * 10 + S[i] - '0';
        get_number_id[i] = number_id;
    }

    return { res, number_id };
}
pair<int,int> dfs_xor(int L, int R) {
    static int xor_id = 0;
    xor_id++;

    int st = L, res = 0;
    int isfirst = 1;
    rep(i, L, R + 1) if(S[i] == '^') {
        auto p = dfs_number(st, i - 1);
        st = i + 1;

        stxor.update(p.second, p.first);
        res ^= p.first;
        get_xor_id[p.second] = xor_id;

        if (isfirst) {
            isfirst = 0;
            start_xor[xor_id] = p.second;
        }
    }

    auto p = dfs_number(st, R);

    stxor.update(p.second, p.first);
    res ^= p.first;
    get_xor_id[p.second] = xor_id;
    end_xor[xor_id] = p.second;
    if (isfirst) start_xor[xor_id] = p.second;

    return { res, xor_id };
}
pair<int,int> dfs_and(int L, int R) {
    static int and_id = 0;
    and_id++;

    int st = L, res = -1;
    int isfirst = 1;
    rep(i, L, R + 1) if (S[i] == '&') {
        auto p = dfs_xor(st, i - 1);
        st = i + 1;

        stand.update(p.second, p.first);

        if (res < 0) res = p.first;
        else res &= p.first;
        get_and_id[p.second] = and_id;

        if (isfirst) {
            isfirst = 0;
            start_and[and_id] = p.second;
        }
    }

    auto p = dfs_xor(st, R);

    stand.update(p.second, p.first);
    if (res < 0) res = p.first;
    else res &= p.first;
    get_and_id[p.second] = and_id;
    end_and[and_id] = p.second;
    if (isfirst) start_and[and_id] = p.second;

    return { res, and_id };
}
pair<int,int> dfs_or(int L, int R) {
    static int or_id = 0;
    or_id++;

    int st = L, res = 0;
    rep(i, L, R + 1) if (S[i] == '|') {
        auto p = dfs_and(st, i - 1);
        st = i + 1;

        stor.update(p.second, p.first);

        res |= p.first;
        get_or_id[p.second] = or_id;
    }

    auto p = dfs_and(st, R);

    stor.update(p.second, p.first);

    res |= p.first;
    get_or_id[p.second] = or_id;

    return { res, or_id };
}
void pre() {
    dfs_or(0, N - 1);
}
//---------------------------------------------------------------------------------------------------
int getnumber(int i, int j) {
    int res = 0;
    while ('0' <= S[i] and S[i] <= '9' and i <= j) res = res * 10 + S[i] - '0', i++;
    return res;
}
int getnumber_back(int i) {
    int res = 0;
    int ten = 1;
    while (0 <= i and '0' <= S[i] and S[i] <= '9') res = res + (S[i] - '0') * ten, ten *= 10, i--;
    return res;
}
int query(int i, int j) {
    int L = getnumber(i, N - 1);
    int R = getnumber_back(j);

    int i_num = get_number_id[i];
    int j_num = get_number_id[j];
    if (i_num == j_num) return getnumber(i, j);

    int i_xor = get_xor_id[i_num];
    int j_xor = get_xor_id[j_num];
    if (i_xor == j_xor) return L ^ stxor.get(i_num + 1, j_num) ^ R;

    L = L ^ stxor.get(i_num + 1, end_xor[i_xor] + 1);
    R = R ^ stxor.get(start_xor[j_xor], j_num);

    int i_and = get_and_id[i_xor];
    int j_and = get_and_id[j_xor];
    if (i_and == j_and) return L & stand.get(i_xor + 1, j_xor) & R;

    L = L & stand.get(i_xor + 1, end_and[i_and] + 1);
    R = R & stand.get(start_and[j_and], j_xor);

    int i_or = get_or_id[i_and];
    int j_or = get_or_id[j_and];

    assert(i_or == j_or);

    return L | stor.get(i_and + 1, j_and) | R;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N >> S >> Q;
    
    pre();

    rep(_, 0, Q) {
        int i, j; cin >> i >> j;
        printf("%d\n", query(i, j));
    }
}
accuracy: 1
time_ms: 60
memory_kb: 6668
final_rank: 4

code_snippet: #include <type_traits>
#include <initializer_list>
#include <cstdint>
#include <cassert>
#include <iterator>
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <algorithm>
namespace loquat {
namespace bitmanip {
template <typename T>
inline auto clz(T x) noexcept ->
	typename std::enable_if<sizeof(int) < sizeof(T), unsigned int>::type
{
	return __builtin_clzll(x);
}
template <typename T>
inline T clp2(T x) noexcept {
	if(x == 0u){ return 0u; }
	return T(1u) << (sizeof(T) * 8u - clz(x - 1));
}
}
}
namespace loquat {
template <typename Impl>
class range_query_behavior_wrapper {
public:
	using value_type = typename Impl::value_type;
private:
	Impl m_impl;
public:
	range_query_behavior_wrapper(Impl impl) : m_impl(std::move(impl)) { }
	value_type identity() const {
		return m_impl.identity();
	}
	value_type merge(const value_type& a, const value_type& b) const {
		return m_impl.merge(a, b);
	}
};
}
namespace loquat {
template <typename Behavior>
class segment_tree {
public:
	using behavior_type = Behavior;
	using value_type = typename behavior_type::value_type;
private:
	size_t m_actual_size;
	std::vector<value_type> m_values;
	range_query_behavior_wrapper<behavior_type> m_behavior;
	void initialize(){
		const auto m = m_values.size() / 2;
		for(size_t i = 0; i < m; ++i){
			const auto k = m - 1 - i;
			m_values[k] = m_behavior.merge(
				m_values[k * 2 + 1], m_values[k * 2 + 2]);
		}
	}
public:
	template <typename Iterator>
	segment_tree(
		Iterator first,
		Iterator last,
		const behavior_type& behavior = behavior_type())
		: m_actual_size(std::distance(first, last))
		, m_values(bitmanip::clp2(m_actual_size) * 2 - 1)
		, m_behavior(behavior)
	{
		const auto it = m_values.begin() + m_values.size() / 2;
		std::copy(first, last, it);
		initialize();
	}
	value_type query(size_t left, size_t right) const {
		const auto m = m_values.size() / 2;
		left += m; right += m;
		value_type l_value = m_behavior.identity(), r_value = l_value;
		while(left < right){
			if((left & 1u) == 0u){
				const auto& x = m_values[left];
				l_value = m_behavior.merge(l_value, x);
			}
			if((right & 1u) == 0u){
				const auto& x = m_values[right - 1];
				r_value = m_behavior.merge(x, r_value);
			}
			left  = left / 2;
			right = (right - 1) / 2;
		}
		return m_behavior.merge(l_value, r_value);
	}
};
}
using namespace std;
struct Number {
	int scale;
	int value;
	Number() : scale(1), value(0) { }
	Number(int n, int v) : scale(n), value(v) { }
	int eval() const { return value; }
	Number merge(const Number& r) const {
		return Number(scale * r.scale, value * r.scale + r.value);
	}
};
template <typename ChildT, typename F, int I>
struct TemplateExpr {
	using self_type = TemplateExpr<ChildT, F, I>;
	bool enable;
	ChildT left;
	ChildT right;
	int imm;
	TemplateExpr() : enable(false), left(), right(), imm(I) { }
	explicit TemplateExpr(const ChildT& l) : enable(false), left(l), right(), imm(I) { }
	TemplateExpr(const ChildT& l, const ChildT& r, int i = I)
		: enable(true), left(l), right(r), imm(i)
	{ }
	int eval() const {
		auto f = F();
		if(!enable){ return left.eval(); }
		return f(f(left.eval(), imm), right.eval());
	}
	self_type merge(const self_type& r) const {
		auto f = F();
		if(!enable && !r.enable){ return self_type(left.merge(r.left)); }
		if(!enable){ return self_type(left.merge(r.left), r.right, r.imm); }
		if(!r.enable){ return self_type(left, right.merge(r.left), imm); }
		return self_type(left, r.right, f(f(imm, right.merge(r.left).eval()), r.imm));
	}
};
using XorExpr = TemplateExpr<Number,  std::bit_xor<int>,  0>;
using AndExpr = TemplateExpr<XorExpr, std::bit_and<int>, -1>;
using OrExpr  = TemplateExpr<AndExpr, std::bit_or<int>,   0>;
struct range_query_behavior {
	using value_type = OrExpr;
	value_type identity() const { return OrExpr(); }
	value_type merge(const value_type& a, const value_type& b) const {
		return a.merge(b);
	}
};
int main(){
	ios_base::sync_with_stdio(false);
	int n, q;
	string s;
	cin >> n >> s >> q;
	vector<OrExpr> init(n);
	for(int i = 0; i < n; ++i){
		if(s[i] == '|'){
			init[i].enable = true;
		}else if(s[i] == '&'){
			init[i].left.enable = true;
		}else if(s[i] == '^'){
			init[i].left.left.enable = true;
		}else{
			init[i].left.left.left = Number(10, s[i] - '0');
		}
	}
	loquat::segment_tree<range_query_behavior> st(init.begin(), init.end());
	while(q--){
		int l, r;
		cin >> l >> r;
		cout << st.query(l, r + 1).eval() << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 44312
final_rank: 10

code_snippet: #include <bits/stdc++.h>
                                            #include<iostream>
                                            #include<cstdio>
                                            #include<vector>
                                            #include<queue>
                                            #include<map>
                                            #include<cstring>
                                            #include<string>
                                            #include <math.h>
                                            #include<algorithm>
                                        //    #include <boost/multiprecision/cpp_int.hpp>
                                            #include<functional>
                                   #define int long long
                                            #define inf  1000000007
                                            #define pa pair<int,int>
                                            #define ll long long
                                            #define pal pair<double,double>
                                            #define ppap pair<pa,int>
                                    //  #define PI 3.14159265358979323846
                                            #define paa pair<int,char>
                                            #define  mp make_pair
                                            #define  pb push_back
                                            #define EPS (1e-10)
                                            #define equals(a,b) (fabs((a)-(b))<EPS)
    int dx[8]={0,-1,0,1,1,1,-1,-1};
    int dy[8]={1,0,-1,0,-1,1,1,-1};
                                            using namespace std;
                                   			class pa3{
                                            	public:
                                            	int x,y,z;
                                            	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                            	bool operator < (const pa3 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		 return z<p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                   				bool operator > (const pa3 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		 return z>p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa3 &p) const{
                                            		return x==p.x && y==p.y && z==p.z;
                                            	}
                                            		bool operator != (const pa3 &p) const{
                                            			return !( x==p.x && y==p.y && z==p.z);
                                            	}
                                            
                                            };
                                            
                                            class pa4{
                                            	public:
                                            	double x;
                                            	int y,z,w;
                                            	pa4(double x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                            	bool operator < (const pa4 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		if(z!=p.z)return z<p.z;
                                            		return w<p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator > (const pa4 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		if(z!=p.z)return z>p.z;
                                            		return w>p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa4 &p) const{
                                            		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                            	}
                                            		
                                            
                                            };
                                            class pa2{
                                            	public:
                                            	int x,y;
                                            	pa2(int x=0,int y=0):x(x),y(y) {}
                                            	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                            	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                            	bool operator < (const pa2 &p) const{
                                            		return y != p.y ? y<p.y: x<p.x;
                                            	}
                                            	bool operator > (const pa2 &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa2 &p) const{
                                            		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                            	}
                                            	bool operator != (const pa2 &p) const{
                                            		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                            	}
                                            		
                                            
                                            };
                                            
                                                   #define ppa pair<int,pas>
                                            class Point{
                                            	public:
                                            	double x,y;
                                            	Point(double x=0,double y=0):x(x),y(y) {}
                                            	Point operator + (Point p) {return Point(x+p.x,y+p.y);}
                                            	Point operator - (Point p) {return Point(x-p.x,y-p.y);}
                                            	Point operator * (double a) {return Point(x*a,y*a);}
                                            	Point operator / (double a) {return Point(x/a,y/a);}
                                            	double absv() {return sqrt(norm());}
                                            	double norm() {return x*x+y*y;}
                                            	bool operator < (const Point &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const Point &p) const{
                                            		return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
                                            	}
                                            };
                                            typedef Point Vector;
                                     #define pl pair<int,pas>
                                            struct Segment{
                                            Point p1,p2;
                                            };
                                             double dot(Vector a,Vector b){
                                            	return a.x*b.x+a.y*b.y;
                                            }
                                            double cross(Vector a,Vector b){
                                            	return a.x*b.y-a.y*b.x;
                                            }
                                        
                bool parareru(Point a,Point b,Point c,Point d){
                //	if(abs(cross(a-b,d-c))<EPS)cout<<"dd "<<cross(a-b,d-c)<<endl;
                	return abs(cross(a-b,d-c))<EPS;
                }
                double distance_ls_p(Point a, Point b, Point c) {
                  if ( dot(b-a, c-a) < EPS ) return (c-a).absv();
                  if ( dot(a-b, c-b) < EPS ) return (c-b).absv();
                  return abs(cross(b-a, c-a)) / (b-a).absv();
                }
                bool is_intersected_ls(Segment a,Segment b) {
                	if(a.p1==b.p1||a.p2==b.p1||a.p1==b.p2||a.p2==b.p2) return false;
                	if(parareru((a.p2),(a.p1),(a.p1),(b.p2))&&parareru((a.p2),(a.p1),(a.p1),(b.p1))){
                //		cout<<"sss"<<endl;
                		if(dot(a.p1-b.p1,a.p1-b.p2)<EPS) return true;
                		if(dot(a.p2-b.p1,a.p2-b.p2)<EPS) return true;
                		if(dot(a.p1-b.p1,a.p2-b.p1)<EPS) return true;
                		if(dot(a.p1-b.p2,a.p2-b.p2)<EPS) return true;
                		return false;
                	}
                  else return ( cross(a.p2-a.p1, b.p1-a.p1) * cross(a.p2-a.p1, b.p2-a.p1) < EPS ) && ( cross(b.p2-b.p1, a.p1-b.p1) * cross(b.p2-b.p1, a.p2-b.p1) < EPS );
                }
                 
                double segment_dis(Segment a,Segment b){
                	if(is_intersected_ls(a,b))return 0;
                	double r=distance_ls_p(a.p1, a.p2, b.p1);
                	r=min(r,distance_ls_p(a.p1, a.p2, b.p2));
                	r=min(r,distance_ls_p(b.p1, b.p2, a.p2));
                	r=min(r,distance_ls_p(b.p1, b.p2, a.p1));
                	return r;
                }
                Point intersection_ls(Segment a, Segment b) {
                  Point ba = b.p2-b.p1;
                  double d1 = abs(cross(ba, a.p1-b.p1));
                  double d2 = abs(cross(ba, a.p2-b.p1));
                  double t = d1 / (d1 + d2);
                 
                  return a.p1 + (a.p2-a.p1) * t;
                }
                 
                                string itos( int i ) {
                                ostringstream s ;
                                s << i ;
                                return s.str() ;
                                }
                                 
                                int gcd(int v,int b){
                                	if(v>b) return gcd(b,v);
                                	if(v==b) return b;
                                	if(b%v==0) return v;
                                	return gcd(v,b%v);
                                }
                 
                                double distans(double x1,double y1,double x2,double y2){
                                	double rr=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                                	return sqrt(rr);
                                	
                                }
                                int mod;
                                
                int pr[500010];
                int inv[500010];
                
                int beki(int wa,int rr,int warukazu){
                	if(rr==0) return 1%warukazu;
                	if(rr==1) return wa%warukazu;
                	if(rr%2==1) return (beki(wa,rr-1,warukazu)*wa)%warukazu;
                	int zx=beki(wa,rr/2,warukazu);
                	return (zx*zx)%warukazu;
                }
    double bekid(double w,int r){
    	if(r==0) return 1.0;
    	if(r==1) return w;
    	if(r%2) return bekid(w,r-1)*w;
    	double f=bekid(w,r/2);
    	return f*f;
    }
                
    			int comb(int nn,int rr){
    				int r=pr[nn]*inv[rr];
    				r%=mod;
    				r*=inv[nn-rr];
    				r%=mod;
    				return r;
    			}
                
                void gya(int ert){
                	pr[0]=1;
                	for(int i=1;i<ert;i++){
                		pr[i]=(pr[i-1]*i)%mod;
                	}
                	for(int i=0;i<ert;i++) inv[i]=beki(pr[i],mod-2,mod);
                	
                }
                
              //   cin.tie(0);
    		//	ios::sync_with_stdio(false);
    			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;            
                 //sort(ve.begin(),ve.end(),greater<int>());
                                         //----------------kokomade tenpure------------
                //vector<double> ans(100000000),ans2(100000000)

///////////////////////////////////////////////////////////
struct segsumxor{
	//       1
	//   2        3
	// 4   5   6    7
	
	
	private:
	public:
	
	// 1<<10 = 1024
	// 1<<11 = 2048
	// 1<<12 = 4096
	// 1<<13 = 8192
	// 1<<14 = 16384
	// 1<<15 = 32768
	// 1<<16 = 65536
	// 1<<17 = 131072
	// 1<<18 = 262144
	
	int cor=(1<<17);
	
	vector<int> vec;
	int tani=0;
	int en(int x,int y){
		return x^y;	
	}
	void shoki1(){
		vec.resize(2*cor+3, tani);
	}
		void shoki2(){
			for(int i=cor-1;i>0;i--) vec[i]=en(vec[2*i],vec[2*i+1]);
		}
	
	
	
	// [a,b)
	// k-th node
	// k no kukanha [l,r)
	int sum(int a,int b,int k=1,int l=0,int r=-10){
		if(r<0)r=cor;
		
	//	cout<<a<<" "<<b<<" "<<k<<" "<<l<<" "<<r<<endl;
		
		if(a<=l && r<=b){
			return vec[k];
		}
		if(r<=a || b<=l){
			return tani;
		}
		
		int v1=sum(a,b,k*2,l,(l+r)/2),v2=sum(a,b,k*2+1,(l+r)/2,r);
		return en(v1,v2);
	}
	
};

struct segsumor{
	//       1
	//   2        3
	// 4   5   6    7
	
	
	private:
	public:
	
	// 1<<10 = 1024
	// 1<<11 = 2048
	// 1<<12 = 4096
	// 1<<13 = 8192
	// 1<<14 = 16384
	// 1<<15 = 32768
	// 1<<16 = 65536
	// 1<<17 = 131072
	// 1<<18 = 262144
	
	int cor=(1<<17);
	
	vector<int> vec;
	int tani=0;
	int en(int x,int y){
		return x|y;	
	}
	void shoki1(){
		vec.resize(2*cor+3, tani);
	}
		void shoki2(){
			for(int i=cor-1;i>0;i--) vec[i]=en(vec[2*i],vec[2*i+1]);
		}
	
	
	
	// [a,b)
	// k-th node
	// k no kukanha [l,r)
	int sum(int a,int b,int k=1,int l=0,int r=-10){
		if(r<0)r=cor;
		
	//	cout<<a<<" "<<b<<" "<<k<<" "<<l<<" "<<r<<endl;
		
		if(a<=l && r<=b){
			return vec[k];
		}
		if(r<=a || b<=l){
			return tani;
		}
		
		int v1=sum(a,b,k*2,l,(l+r)/2),v2=sum(a,b,k*2+1,(l+r)/2,r);
		return en(v1,v2);
	}
	
};

struct segsumand{
	//       1
	//   2        3
	// 4   5   6    7
	
	
	private:
	public:
	
	// 1<<10 = 1024
	// 1<<11 = 2048
	// 1<<12 = 4096
	// 1<<13 = 8192
	// 1<<14 = 16384
	// 1<<15 = 32768
	// 1<<16 = 65536
	// 1<<17 = 131072
	// 1<<18 = 262144
	
	int cor=(1<<17);
	
	vector<int> vec;
	int tani=(1ll<<31)-1;
	int en(int x,int y){
		return x&y;	
	}
	void shoki1(){
		vec.resize(2*cor+3, tani);
	}
		void shoki2(){
			for(int i=cor-1;i>0;i--) vec[i]=en(vec[2*i],vec[2*i+1]);
		}
	
	
	
	// [a,b)
	// k-th node
	// k no kukanha [l,r)
	int sum(int a,int b,int k=1,int l=0,int r=-10){
		if(r<0)r=cor;
		
	//	cout<<a<<" "<<b<<" "<<k<<" "<<l<<" "<<r<<endl;
		
		if(a<=l && r<=b){
			return vec[k];
		}
		if(r<=a || b<=l){
			return tani;
		}
		
		int v1=sum(a,b,k*2,l,(l+r)/2),v2=sum(a,b,k*2+1,(l+r)/2,r);
		return en(v1,v2);
	}
	
};

segsumor Sor;
segsumand Sand;
segsumxor Sxor;
///////////////////////////////
int a[4][100200]={0};

int val[4][100200]={0};

vector<pa> ve[4];

int sxor(int l,int r){
	return Sxor.sum(l,r);
}

int sand(int l,int r){
return	Sand.sum(l,r);
}

int sor(int l,int r){
return	Sor.sum(l,r);
}
string s;
int solve4(int l,int r){
	int ans=0;
	for(int i=l;i<=r;i++){
	ans*=10;
		ans+=s[i]-'0';
	}
//	cout<<"solve4 "<<l<<" "<<r<<" "<<ans<<endl;
	return ans;
}

int solve3(int l,int r){
	int ans;
	if(a[3][l]==a[3][r]) ans= solve4(l,r);
	else  ans=sxor(a[3][l]+1,a[3][r])^solve4(ve[3][a[3][r]].first,r)^solve4(l,ve[3][a[3][l]].second);
//	cout<<"solve3 "<<l<<" "<<r<<" "<<ans<<endl;
	return ans;
}

int solve2(int l,int r) {// 0~9, ^,&
	int ans;
	if(a[2][l]==a[2][r]) ans= solve3(l,r);
	else ans=sand(a[2][l]+1,a[2][r])&solve3(ve[2][a[2][r]].first,r)&solve3(l,ve[2][a[2][l]].second);
//	cout<<"solve2 "<<l<<" "<<r<<" "<<ans<<endl;
	return ans;
}

int solve(int l,int r){
	int ans;
	if(a[1][l]==a[1][r]) ans= solve2(l,r);
	else  ans=sor(a[1][l]+1,a[1][r])|solve2(ve[1][a[1][r]].first,r)|solve2(l,ve[1][a[1][l]].second);
//	cout<<"solve1 "<<l<<" "<<r<<" "<<ans<<endl;
	return ans;
}

    signed main(){
     
    	       cin.tie(0);
    			ios::sync_with_stdio(false);
int n,q;
    	cin>>n;
    	
    	
    	n++;
    	cin>>s;
    	s+="|";
    	for(int i=0;i<100200;i++)val[1][i]=(1ll<<31)-1;
    	int ima=0;
    	int si=0;
    	for(int i=0;i<n;i++){
    		if(s[i]>='0' && s[i]<='9'){
    			a[3][i]=ima;
    			val[3][ima]*=10;
    			val[3][ima]+=s[i]-'0';
    		}
    		else{
    			
    			ve[3].pb(mp(si,i-1));
    			si=i+1;
    			ima++;
    		}
    	}
    	
    	ima=0;
    	si=0;
    	for(int i=0;i<n;i++){
    		
    		if(s[i]!='&' && s[i]!='|'){
    			a[2][i]=ima;
    			if(s[i]=='^'){
    				val[2][ima]^= val[3][a[3][i-1]];
    			}
    		}
    		else{
    			
    			ve[2].pb(mp(si,i-1));
    			si=i+1;
    			val[2][ima]^= val[3][a[3][i-1]];
    			
    			ima++;
    		}
    	}
    
    	ima=0;
    	si=0;
    	for(int i=0;i<n;i++){
    		if( s[i]!='|'){
    			a[1][i]=ima;
    			if(s[i]=='&'){
    	
    				val[1][ima]&= val[2][a[2][i-1]];
   
    			}
    		}
    		else {
    			ve[1].pb(mp(si,i-1));
    			si=i+1;
    				val[1][ima]&= val[2][a[2][i-1]];

    			ima++;
    		}
    	}
    	
    	Sor.shoki1();
    	Sxor.shoki1();
    	Sand.shoki1();
    	for(int i=0;i<=100000;i++)Sxor.vec[Sxor.cor+i]=val[3][i];
    	for(int i=0;i<=100000;i++)Sand.vec[Sxor.cor+i]=val[2][i];
    	for(int i=0;i<=100000;i++)Sor.vec[Sxor.cor+i]=val[1][i];
    	Sor.shoki2();
    	Sxor.shoki2();
    	Sand.shoki2();
    	cin>>q;
    	
    	for(int i=0;i<q;i++){
    		int l,r;
    		cin>>l>>r;
    		cout<<solve(l,r)<<endl;
    	}
   
  	return 0;
    }
accuracy: 1
time_ms: 150
memory_kb: 12768
final_rank: 7

code_snippet: #include <functional>
#include <iostream>
#include <vector>
#define int long long
using namespace std;

template<typename F> int binarySearchU(int low, int up, const F &f) {
  while (up - low > 1) {
    int mid = low + (up - low) / 2;
    (f(mid) ? up : low) = mid;
  }
  return up;
}

template<typename F> int binarySearchL(int low, int up, const F &f) {
  while (up - low > 1) {
    int mid = low + (up - low) / 2;
    (f(mid) ? low : up) = mid;
  }
  return low;
}

class DisjointSparseTable {
  using T = int;
  using F = function<T(T, T)>;
  T unit;
  F f;
  vector<int> logTable;
  vector<vector<T>> table;

public:
  DisjointSparseTable() {}
  DisjointSparseTable(const vector<T> &v, T unit, const F &f) : unit(unit), f(f) {
    int n = v.size();
    int size = 1;
    while (size < n) size *= 2;
    logTable.resize(size + 1);
    for (int i = 2; i <= size; i++) logTable[i] = logTable[i >> 1] + 1;
    int k = logTable[size];
    table.resize(k + 2, vector<T>(size, unit));
    copy(v.begin(), v.end(), table[1].begin());
    for (int h = 2, range; (range = 1 << h) <= size; h++) {
      int half = range >> 1;
      for (int i = half; i < size; i += range) {
        table[h][i - 1] = table[1][i - 1];
        for (int j = i - 2; j >= i - half; j--) table[h][j] = f(table[1][j], table[h][j + 1]);
        table[h][i] = table[1][i];
        for (int j = i + 1; j < i + half; j++) table[h][j] = f(table[h][j - 1], table[1][j]);
      }
    }
  }

  T fold(int l, int r) { // [l, r)
    if (l == r) return unit;
    if (l == --r) return table[1][l];
    int h = logTable[l ^ r] + 1;
    return f(table[h][l], table[h][r]);
  }
};

struct AST {
  char op = '?';
  int l = 0, r = 0; // [l, r)
  int value = 0;
  vector<AST> child;
  DisjointSparseTable dst;

  AST(char op) : op(op) {}
  AST(int value, int l, int r) : value(value), l(l), r(r) {}

  int eval(int a, int b) { // [a, b)
    if (child.empty()) return stoi(to_string(value).substr(a - l, b - a));
    if (op == '^') return fold(+0, a, b, [](int x, int y) { return x ^ y; });
    if (op == '&') return fold(-1, a, b, [](int x, int y) { return x & y; });
    if (op == '|') return fold(+0, a, b, [](int x, int y) { return x | y; });
  }

private:
  template<typename F> int fold(int unit, int a, int b, const F &f) {
    int n = child.size();
    if (n == 1) return child[0].eval(a, b);
    int x = binarySearchU(-1, n, [&](int k) { return k == n || a < child[k].l; });
    int y = binarySearchL(-1, n, [&](int k) { return k == -1 || child[k].r < b; });
    if (x == y + 2) return child[y + 1].eval(a, b);
    if (x == y + 1) return f(child[x - 1].eval(a, child[x - 1].r), child[y + 1].eval(child[y + 1].l, b));
    unit = f(unit, child[x - 1].eval(a, child[x - 1].r));
    unit = f(unit, dst.fold(x, y + 1));
    unit = f(unit, child[y + 1].eval(child[y + 1].l, b));
    return unit;
  }
};

string S;

template<typename F> AST p_op(int &i, char op, const F &f) {
  AST ast(op);
  ast.l = i;
  ast.child.emplace_back(f(i));
  while (S[i] == op) ast.child.emplace_back(f(++i));
  ast.r = i;
  vector<int> v;
  for (auto &c : ast.child) v.emplace_back(c.eval(c.l, c.r));
  if (op == '^') ast.dst = DisjointSparseTable(v, +0, [](int x, int y) { return x ^ y; });
  if (op == '&') ast.dst = DisjointSparseTable(v, -1, [](int x, int y) { return x & y; });
  if (op == '|') ast.dst = DisjointSparseTable(v, +0, [](int x, int y) { return x | y; });
  return ast;
}

AST p_number(int &i) {
  int l = i;
  int val = 0;
  while (isdigit(S[i])) val = val * 10 + S[i++] - '0';
  return AST(val, l, i);
}

AST p_xor(int &i) { return p_op(i, '^', p_number); }
AST p_and(int &i) { return p_op(i, '&', p_xor); }
AST p_or(int &i) { return p_op(i, '|', p_and); }

signed main() {
  int N;
  cin >> N;
  cin >> S;
  int p = 0;
  AST ast = p_or(p);
  int Q;
  cin >> Q;
  while (Q--) {
    int l, r;
    cin >> l >> r;
    ++r;
    cout << ast.eval(l, r) << endl;
  }
}
accuracy: 1
time_ms: 220
memory_kb: 9456
final_rank: 9

code_snippet: #include <functional>
#include <iostream>
#include <vector>
#define int long long
using namespace std;

template<typename F> int binarySearchU(int low, int up, const F &f) {
  while (up - low > 1) {
    int mid = low + (up - low) / 2;
    (f(mid) ? up : low) = mid;
  }
  return up;
}

template<typename F> int binarySearchL(int low, int up, const F &f) {
  while (up - low > 1) {
    int mid = low + (up - low) / 2;
    (f(mid) ? low : up) = mid;
  }
  return low;
}

class SegTree {
  using T = int;
  using F = function<int(int, int)>;
  T unit;
  F f;
  vector<T> tree; // 1-indexed
  int size = 1;

public:
  SegTree() {}
  SegTree(const vector<T> &v, const T &unit, const F &f) : unit(unit), f(f) {
    int n = v.size();
    while (size < n) size *= 2;
    tree.assign(size * 2, unit);
    copy(v.begin(), v.end(), tree.begin() + size);
    for (int i = size - 1; i >= 1; i--) tree[i] = f(tree[i * 2], tree[i * 2 + 1]);
  }

  T fold(int l, int r) { // [l, r)
    T accl = unit, accr = unit;
    for (l += size, r += size; l < r; l /= 2, r /= 2) {
      if (l & 1) accl = f(accl, tree[l++]);
      if (r & 1) accr = f(tree[--r], accr);
    }
    return f(accl, accr);
  }
};

struct AST {
  char op = '?';
  int l = 0, r = 0; // [l, r)
  int value = 0;
  vector<AST> child;
  SegTree st;

  AST(char op) : op(op) {}
  AST(int value, int l, int r) : value(value), l(l), r(r) {}

  int eval(int a, int b) { // [a, b)
    if (child.empty()) return stoi(to_string(value).substr(a - l, b - a));
    if (op == '^') return fold(+0, a, b, [](int x, int y) { return x ^ y; });
    if (op == '&') return fold(-1, a, b, [](int x, int y) { return x & y; });
    if (op == '|') return fold(+0, a, b, [](int x, int y) { return x | y; });
  }

private:
  template<typename F> int fold(int unit, int a, int b, const F &f) {
    int n = child.size();
    if (n == 1) return child[0].eval(a, b);
    int x = binarySearchU(-1, n, [&](int k) { return k == n || a < child[k].l; });
    int y = binarySearchL(-1, n, [&](int k) { return k == -1 || child[k].r < b; });
    if (x == y + 2) return child[y + 1].eval(a, b);
    if (x == y + 1) return f(child[x - 1].eval(a, child[x - 1].r), child[y + 1].eval(child[y + 1].l, b));
    unit = f(unit, child[x - 1].eval(a, child[x - 1].r));
    unit = f(unit, st.fold(x, y + 1));
    unit = f(unit, child[y + 1].eval(child[y + 1].l, b));
    return unit;
  }
};

string S;

template<typename F> AST p_op(int &i, char op, const F &f) {
  AST ast(op);
  ast.l = i;
  ast.child.emplace_back(f(i));
  while (S[i] == op) ast.child.emplace_back(f(++i));
  ast.r = i;
  vector<int> v;
  for (auto &c : ast.child) v.emplace_back(c.eval(c.l, c.r));
  if (op == '^') ast.st = SegTree(v, +0, [](int x, int y) { return x ^ y; });
  if (op == '&') ast.st = SegTree(v, -1, [](int x, int y) { return x & y; });
  if (op == '|') ast.st = SegTree(v, +0, [](int x, int y) { return x | y; });
  return ast;
}

AST p_number(int &i) {
  int l = i;
  int val = 0;
  while (isdigit(S[i])) val = val * 10 + S[i++] - '0';
  return AST(val, l, i);
}

AST p_xor(int &i) { return p_op(i, '^', p_number); }
AST p_and(int &i) { return p_op(i, '&', p_xor); }
AST p_or(int &i) { return p_op(i, '|', p_and); }

signed main() {
  int N;
  cin >> N;
  cin >> S;
  int p = 0;
  AST ast = p_or(p);
  int Q;
  cin >> Q;
  while (Q--) {
    int l, r;
    cin >> l >> r;
    ++r;
    cout << ast.eval(l, r) << endl;
  }
}
accuracy: 1
time_ms: 220
memory_kb: 6968
final_rank: 8