#include <bits/stdc++.h>
using namespace std;
int n, m, X;
int a[100010];
struct node {
  vector<pair<int, int> > L, R;
  long long ret;
  node() {
    L.clear(), R.clear();
    ret = 0;
  }
} s[400010];
node merge(const node &L, const node &R) {
  node ret;
  int orL = 0, orR = 0;
  long long sumL = 0, sumR = 0;
  for (auto w : L.L) orL |= w.first, ret.L.push_back(w);
  for (auto w : R.R) orR |= w.first, ret.R.push_back(w);
  for (auto w : R.L) {
    orL |= w.first, sumR += w.second;
    if (!ret.L.empty() && orL == (ret.L.rbegin()->first))
      (ret.L.rbegin()->second) += w.second;
    else
      ret.L.push_back({orL, w.second});
  }
  for (auto w : L.R) {
    orR |= w.first, sumL += w.second;
    if (!ret.R.empty() && orR == ret.R.rbegin()->first)
      ret.R.rbegin()->second += w.second;
    else
      ret.R.push_back({orR, w.second});
  }
  ret.ret = L.ret + R.ret + sumL * sumR;
  int pos = L.R.size() - 1;
  for (auto w : R.L) {
    while (pos >= 0 && (L.R[pos].first | w.first) >= X)
      sumL -= L.R[pos].second, pos--;
    ret.ret -= w.second * sumL;
  }
  return ret;
}
void update(int i, int l, int r, int pos, int v) {
  if (l == r) {
    s[i].L.clear(), s[i].R.clear();
    s[i].L.push_back({v, 1}), s[i].R.push_back({v, 1});
    s[i].ret = (v >= X);
  } else {
    int mid = (l + r) >> 1;
    if (pos <= mid)
      update(i << 1, l, mid, pos, v);
    else
      update(i << 1 ^ 1, mid + 1, r, pos, v);
    s[i] = merge(s[i << 1], s[i << 1 ^ 1]);
  }
}
void build(int i, int l, int r) {
  if (l == r) {
    s[i].L.push_back({a[l], 1}), s[i].R.push_back({a[l], 1});
    s[i].ret = (a[l] >= X);
  } else {
    int mid = (l + r) >> 1;
    build(i << 1, l, mid);
    build(i << 1 ^ 1, mid + 1, r);
    s[i] = merge(s[i << 1], s[i << 1 ^ 1]);
  }
}
node query(int i, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr)
    return s[i];
  else {
    int mid = (l + r) >> 1;
    if (ql > mid)
      return query(i << 1 ^ 1, mid + 1, r, ql, qr);
    else if (qr <= mid)
      return query(i << 1, l, mid, ql, qr);
    else
      return merge(query(i << 1, l, mid, ql, qr),
                   query(i << 1 ^ 1, mid + 1, r, ql, qr));
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &X);
  for (int i = 1; i <= n; i++) scanf("%d", a + i);
  build(1, 1, n);
  int op, l, r;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &op, &l, &r);
    if (op == 1)
      update(1, 1, n, l, r);
    else
      printf("%lld\n", query(1, 1, n, l, r).ret);
  }
  return 0;
}
