#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, X, a[N];
set<int> pos[20];
int sta[22], top, stk[22], tk;
namespace sgt {
int cov[N << 2], mn[N << 2];
long long s[N << 2];
inline void update(int o) {
  mn[o] = min(mn[o << 1], mn[o << 1 | 1]), s[o] = s[o << 1] + s[o << 1 | 1];
}
inline void pushdown(int o, int len) {
  int& x = cov[o];
  cov[o << 1] = cov[o << 1 | 1] = mn[o << 1] = mn[o << 1 | 1] = x;
  s[o << 1] = x * (long long)(len + 1 >> 1),
         s[o << 1 | 1] = x * (long long)(len >> 1), x = 0;
}
void modify(int l, int r, int o, const int& L, const int& R, const int& val) {
  if (L <= l && r <= R)
    cov[o] = mn[o] = val, s[o] = (r - l + 1LL) * val;
  else {
    if (cov[o]) pushdown(o, r - l + 1);
    const int mid = l + r >> 1;
    if (L <= mid) modify(l, mid, o << 1, L, R, val);
    if (mid < R) modify(mid + 1, r, o << 1 | 1, L, R, val);
    update(o);
  }
}
long long query(int l, int r, int o, const int& L, const int& R) {
  if (L <= l && r <= R) return s[o];
  if (cov[o]) pushdown(o, r - l + 1);
  const int mid = l + r >> 1;
  long long res = 0;
  if (L <= mid) res = query(l, mid, o << 1, L, R);
  if (mid < R) res += query(mid + 1, r, o << 1 | 1, L, R);
  return res;
}
int find(int l, int r, int o, const int& v) {
  if (mn[o] > v) return 0;
  if (l == r) return l;
  if (cov[o]) pushdown(o, r - l + 1);
  const int mid = l + r >> 1;
  int res = find(mid + 1, r, o << 1 | 1, v);
  if (res == 0) res = find(l, mid, o << 1, v);
  return res;
}
}  // namespace sgt
void modify(int p, int v) {
  for (int i = 0; i < 20; ++i)
    if (a[p] >> i & 1) pos[i].erase(p);
  a[p] = v;
  for (int i = 0; i < 20; ++i)
    if (v >> i & 1) pos[i].insert(p);
  tk = top = 0;
  for (int i = 0; i < 20; ++i) {
    auto it = pos[i].upper_bound(p);
    if (it != pos[i].end()) sta[++top] = *it << 5 | i;
    if (it != pos[i].begin()) stk[++tk] = *--it << 5 | i;
  }
  sort(sta + 1, sta + top + 1), sort(stk + 1, stk + tk + 1, greater<int>());
  sta[top + 1] = (n + 1) << 5, stk[tk + 1] = 0, sta[0] = (p + 1) << 5;
  int t = (stk[1] >> 5) + 1, nw = 0, zt = 0;
  for (int i = 1; i <= tk; ++i) zt |= 1 << (stk[i] & 31);
  for (int i = 0, it = tk; i <= top; ++i) {
    int l = sta[i] >> 5, r = (sta[i + 1] >> 5) - 1;
    if (i) nw |= 1 << (sta[i] & 31);
    if (nw > X) break;
    while (it && (zt | nw) > X) zt ^= 1 << (stk[it--] & 31);
    int L = (stk[it + 1] >> 5) + 1;
    if (l <= r) sgt::modify(1, n, 1, l, r, L);
  }
  nw = v;
  for (int i = 1; i <= tk; ++i) {
    nw |= 1 << (stk[i] & 31);
    if (nw > X) break;
    t = (stk[i + 1] >> 5) + 1;
  }
  sgt::modify(1, n, 1, p, p, t);
}
long long query(int l, int r) {
  int ps = sgt::find(1, n, 1, l - 1);
  ps = max(ps, l - 1), ps = min(ps, r);
  long long ans = ps + 1 <= r ? -sgt::query(1, n, 1, ps + 1, r) : 0;
  ans += r - ps;
  ans += (ps - l + 2) * (ps - l + 1LL) / 2;
  ans += (r + ps + 1LL) * (r - ps) / 2;
  ans = (r - l + 1LL) * (r - l + 2) / 2 - ans;
  return ans;
}
int main() {
  scanf("%d%d%d", &n, &m, &X), --X;
  for (int i = 1; i <= n; ++i) {
    scanf("%d", a + i), top = 0;
    for (int w = 0; w < 20; ++w) {
      if (a[i] >> w & 1) pos[w].insert(i);
      if (!pos[w].empty()) sta[++top] = *pos[w].rbegin() << 5 | w;
    }
    sort(sta + 1, sta + top + 1, greater<int>());
    sta[top + 1] = 0;
    int nw = 0, L = (sta[1] >> 5) + 1;
    for (int j = 1; j <= top; ++j) {
      nw |= 1 << (sta[j] & 31);
      if (nw > X) break;
      L = (sta[j + 1] >> 5) + 1;
    }
    sgt::modify(1, n, 1, i, i, L);
  }
  while (m--) {
    int op, l, r;
    scanf("%d%d%d", &op, &l, &r);
    if (op == 1)
      modify(l, r);
    else
      printf("%lld\n", query(l, r));
  }
  return 0;
}
