#include <bits/stdc++.h>
using namespace std;
struct myvi {
  int tt, v[22];
  myvi(int t) : tt(t) { memset(v, 0, sizeof(v)); }
  void emplace_back(int val) { v[tt++] = val; }
  int size() { return tt; }
  int& operator[](int i) { return v[i]; }
  int& back() { return v[tt - 1]; }
};
struct Node {
  myvi pref, qp, suf, qs;
  long long ans;
  Node() : pref(1), qp(1), suf(1), qs(1), ans(0) {}
};
int n, m, first, vet[101010];
Node st[101010 * 4];
Node merge(Node a, Node b) {
  Node ret;
  ret.pref = a.pref;
  ret.qp = a.qp;
  for (auto i = (0); i < (((int)(b.pref).size())); i++) {
    if (ret.pref.back() != (ret.pref.back() | b.pref[i])) {
      ret.pref.emplace_back(ret.pref.back() | b.pref[i]);
      ret.qp.emplace_back(0);
    }
    ret.qp.back() += b.qp[i];
  }
  ret.suf = b.suf;
  ret.qs = b.qs;
  for (auto i = (0); i < (((int)(a.suf).size())); i++) {
    if (ret.suf.back() != (ret.suf.back() | a.suf[i])) {
      ret.suf.emplace_back(ret.suf.back() | a.suf[i]);
      ret.qs.emplace_back(0);
    }
    ret.qs.back() += a.qs[i];
  }
  ret.ans = a.ans + b.ans;
  long long s = 0;
  int r = ((int)(b.pref).size());
  for (auto l = (0); l < (((int)(a.suf).size())); l++) {
    while (r > 0 && (a.suf[l] | b.pref[r - 1]) >= first) s += b.qp[--r];
    ret.ans += s * a.qs[l];
  }
  return ret;
}
void build(int b, int l, int r) {
  if (l == r) {
    st[b].pref[0] = st[b].suf[0] = vet[l];
    st[b].qs[0] = st[b].qp[0] = 1;
    st[b].ans = (vet[l] >= first);
    return;
  }
  int fe = b << 1, fd = fe | 1, m = (l + r) >> 1;
  build(fe, l, m), build(fd, m + 1, r);
  st[b] = merge(st[fe], st[fd]);
}
void upd(int b, int l, int r, int p, int val) {
  if (p < l || r < p) return;
  if (l == r) {
    st[b].pref[0] = st[b].suf[0] = val;
    st[b].qs[0] = st[b].qp[0] = 1;
    st[b].ans = (val >= first);
    return;
  }
  int fe = b << 1, fd = fe | 1, m = (l + r) >> 1;
  upd(fe, l, m, p, val), upd(fd, m + 1, r, p, val);
  st[b] = merge(st[fe], st[fd]);
}
Node query(int b, int l, int r, int first, int second) {
  if (l > second || r < first) return Node();
  if (first <= l && r <= second) return st[b];
  int fe = b << 1, fd = fe | 1, m = (l + r) >> 1;
  return merge(query(fe, l, m, first, second),
               query(fd, m + 1, r, first, second));
}
int main() {
  scanf("%d%d%d", &n, &m, &first);
  for (auto i = (0); i < (n); i++) scanf("%d", vet + i);
  build(1, 0, n - 1);
  while (m--) {
    int tp, a, b;
    scanf("%d%d%d", &tp, &a, &b);
    if (tp == 1)
      upd(1, 0, n - 1, a - 1, b);
    else
      printf("%lld\n", query(1, 0, n - 1, a - 1, b - 1).ans);
  }
}
