#include <bits/stdc++.h>
using namespace std;
struct node {
  vector<pair<int, int> > l, r;
  long long sum;
};
node st[400005];
int a[100005];
int n, m, x;
node merge(node a, node b) {
  node ans;
  ans.sum = a.sum + b.sum;
  int val = 0, pv = -1;
  for (int i = 0; i < (int)(a.l).size(); i++) {
    val |= a.l[i].first;
    if (val != pv) ans.l.emplace_back(make_pair(val, a.l[i].second));
    pv = val;
  }
  for (int i = 0; i < (int)(b.l).size(); i++) {
    val |= b.l[i].first;
    if (val != pv) ans.l.emplace_back(make_pair(val, b.l[i].second));
    pv = val;
  }
  val = 0, pv = -1;
  for (int i = 0; i < (int)(b.r).size(); i++) {
    val |= b.r[i].first;
    if (val != pv) ans.r.emplace_back(make_pair(val, b.r[i].second));
    pv = val;
  }
  for (int i = 0; i < (int)(a.r).size(); i++) {
    val |= a.r[i].first;
    if (val != pv) ans.r.emplace_back(make_pair(val, a.r[i].second));
    pv = val;
  }
  int j = (int)(b.l).size() - 1;
  for (int i = 0; i < (int)(a.r).size(); i++) {
    int l = 0;
    if (i == (int)(a.r).size() - 1)
      l = a.l[0].second;
    else
      l = a.r[i + 1].second + 1;
    int le1 = a.r[i].second - l + 1;
    while (j >= 0 && (a.r[i].first | b.l[j].first) >= x) j--;
    if (j == (int)(b.l).size() - 1) continue;
    int r = b.l[j + 1].second;
    int le2 = b.r[0].second - r + 1;
    ans.sum += le1 * 1ll * le2;
  }
  return ans;
}
void build(int n, int s, int e) {
  if (s == e) {
    st[n].l.emplace_back(make_pair(a[s], s));
    st[n].r.emplace_back(make_pair(a[s], s));
    if (a[s] >= x)
      st[n].sum = 1;
    else
      st[n].sum = 0;
  } else {
    int mid = (s + e) / 2;
    build(n + n, s, mid);
    build(n + n + 1, mid + 1, e);
    st[n] = merge(st[n + n], st[n + n + 1]);
  }
}
void update(int n, int s, int e, int idx) {
  if (s == e) {
    st[n].l.clear();
    st[n].r.clear();
    st[n].l.emplace_back(make_pair(a[s], s));
    st[n].r.emplace_back(make_pair(a[s], s));
    if (a[s] >= x)
      st[n].sum = 1;
    else
      st[n].sum = 0;
  } else {
    int mid = (s + e) / 2;
    if (idx <= mid)
      update(n + n, s, mid, idx);
    else
      update(n + n + 1, mid + 1, e, idx);
    st[n] = merge(st[n + n], st[n + n + 1]);
  }
}
node query(int n, int s, int e, int l, int r) {
  if (s > r || l > e) {
    node ans;
    ans.sum = 0;
    ans.l.clear();
    ans.r.clear();
    return ans;
  }
  if (l <= s && e <= r) return st[n];
  int mid = (s + e) / 2;
  node q1 = query(n + n, s, mid, l, r);
  node q2 = query(n + n + 1, mid + 1, e, l, r);
  return merge(q1, q2);
}
int main() {
  scanf("%d%d%d", &n, &m, &x);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      int idx, y;
      scanf("%d%d", &idx, &y);
      a[idx] = y;
      update(1, 1, n, idx);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      node q = query(1, 1, n, l, r);
      printf("%lld\n", q.sum);
    }
  }
}
