#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, m, v, A[maxn];
struct SegTree {
  int l, r;
  long long s;
  vector<pair<int, int> > L, R;
  SegTree() {
    l = r = 0, s = 0;
    L.clear(), R.clear();
  }
} T[maxn << 2];
SegTree operator+(const SegTree &a, const SegTree &b) {
  SegTree c;
  c.s = a.s + b.s;
  c.l = a.l, c.r = b.r;
  for (int i = 0, j = b.L.size() - 1; i + 1 < a.R.size(); ++i) {
    for (; j > 0 && (a.R[i].first | b.L[j - 1].first) >= v; --j)
      ;
    c.s +=
        1LL * (a.R[i].second - a.R[i + 1].second) * (b.r - b.L[j].second + 1);
  }
  c.L = a.L;
  c.L.pop_back();
  for (int j = 0, now = c.L[c.L.size() - 1].first; j + 1 < b.L.size(); ++j) {
    if ((b.L[j].first | now) > now) {
      now |= b.L[j].first;
      c.L.push_back(make_pair(now, b.L[j].second));
    }
  }
  c.L.push_back(make_pair(1 << 20, c.r + 1));
  c.R = b.R;
  c.R.pop_back();
  for (int i = 0, now = c.R[c.R.size() - 1].first; i + 1 < a.R.size(); ++i) {
    if ((a.R[i].first | now) > now) {
      now |= a.R[i].first;
      c.R.push_back(make_pair(now, a.R[i].second));
    }
  }
  c.R.push_back(make_pair(1 << 20, c.l - 1));
  return c;
}
void Build(int rt, int l, int r) {
  T[rt].l = l, T[rt].r = r;
  if (l == r) {
    T[rt].L.clear(), T[rt].R.clear();
    T[rt].s = (A[l] >= v);
    T[rt].L.push_back(make_pair(A[l], l));
    T[rt].L.push_back(make_pair(1 << 20, l + 1));
    T[rt].R.push_back(make_pair(A[l], l));
    T[rt].R.push_back(make_pair(1 << 20, l - 1));
    return;
  }
  Build((rt << 1), l, ((l + r) >> 1));
  Build((rt << 1 | 1), ((l + r) >> 1) + 1, r);
  T[rt] = T[(rt << 1)] + T[(rt << 1 | 1)];
}
void Modify(int rt, int l, int r, int x) {
  if (l == r) {
    T[rt].L.clear(), T[rt].R.clear();
    T[rt].s = (A[l] >= v);
    T[rt].L.push_back(make_pair(A[l], l));
    T[rt].L.push_back(make_pair(1 << 20, l + 1));
    T[rt].R.push_back(make_pair(A[l], l));
    T[rt].R.push_back(make_pair(1 << 20, l - 1));
    return;
  }
  if (x <= ((l + r) >> 1))
    Modify((rt << 1), l, ((l + r) >> 1), x);
  else
    Modify((rt << 1 | 1), ((l + r) >> 1) + 1, r, x);
  T[rt] = T[(rt << 1)] + T[(rt << 1 | 1)];
}
SegTree Query(int rt, int l, int r, int s, int t) {
  if (s <= l && t >= r) return T[rt];
  if (t <= ((l + r) >> 1)) return Query((rt << 1), l, ((l + r) >> 1), s, t);
  if (s > ((l + r) >> 1))
    return Query((rt << 1 | 1), ((l + r) >> 1) + 1, r, s, t);
  return Query((rt << 1), l, ((l + r) >> 1), s, t) +
         Query((rt << 1 | 1), ((l + r) >> 1) + 1, r, s, t);
}
int main() {
  scanf("%d%d%d", &n, &m, &v);
  for (int i = 1; i <= n; ++i) scanf("%d", &A[i]);
  Build(1, 1, n);
  while (m--) {
    int opt, x, y;
    scanf("%d%d%d", &opt, &x, &y);
    if (opt == 1) {
      A[x] = y;
      Modify(1, 1, n, x);
    } else
      printf("%lld\n", Query(1, 1, n, x, y).s);
  }
  return 0;
}
