#include <bits/stdc++.h>
using namespace std;
long long read() {
  long long s = 0, w = 1;
  char c;
  while (c = getchar(), c > '9' || c < '0')
    if (c == '-') w = -1;
  while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
  return s * w;
}
void write(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(long long x) {
  write(x);
  puts("");
}
const long long N = 1e5 + 7, B = 20, inf = 1e9;
long long n, m, x;
long long a[N];
struct tree {
  long long la[B], ra[B];
  long long ans;
} tr[N << 2];
long long chu(tree ls, tree rs, long long l, long long r, long long mid) {
  long long ln = 0, rn = 0;
  long long la[B + 2], ra[B + 2];
  long long las[B + 2], ras[B + 2];
  for (long long i = 0; i < B; i++)
    if (ls.ra[i]) ra[++rn] = ls.ra[i];
  for (long long i = 0; i < B; i++)
    if (rs.la[i] <= n) la[++ln] = rs.la[i];
  sort(la + 1, la + ln + 1);
  sort(ra + 1, ra + rn + 1);
  ln = unique(la + 1, la + ln + 1) - la - 1;
  rn = unique(ra + 1, ra + rn + 1) - ra - 1;
  if (!ln && !rn) return x == 0 ? (mid - l + 1) * (r - mid) : 0;
  las[0] = 0;
  ras[rn + 1] = 0;
  ra[rn + 1] = mid;
  la[0] = mid + 1;
  if (!ln) {
    for (long long i = rn; i >= 1; i--) ras[i] = ras[i + 1] | a[ra[i]];
    for (long long i = rn + 1; i >= 1; i--) {
      if (ras[i] >= x) return (ra[i] - l + 1) * (r - mid);
    }
  } else if (!rn) {
    for (long long i = 1; i <= ln; i++) las[i] = las[i - 1] | a[la[i]];
    for (long long i = 0; i <= ln; i++) {
      if (las[i] >= x) return (mid - l + 1) * (r - la[i] + 1);
    }
  } else {
    long long ans = 0;
    for (long long i = rn; i >= 1; i--) ras[i] = ras[i + 1] | a[ra[i]];
    for (long long i = 1; i <= ln; i++) las[i] = las[i - 1] | a[la[i]];
    for (long long i = 1, j = 0; i <= rn; i++) {
      while (j <= ln && (ras[i] | las[j]) < x) j++;
      if (j > ln) break;
      ans += (ra[i] - (i == 1 ? l - 1 : ra[i - 1])) * (r - la[j] + 1);
    }
    if (ras[rn] != mid) {
      long long j = 0;
      while (j <= ln && las[j] < x) j++;
      if (j <= ln) ans += (mid - ra[rn]) * (r - la[j] + 1);
    }
    return ans;
  }
  return 0;
}
tree pushup(tree ls, tree rs, long long l, long long r, long long mid) {
  tree c;
  for (long long i = 0; i < B; i++) {
    c.la[i] = min(ls.la[i], rs.la[i]);
    c.ra[i] = max(ls.ra[i], rs.ra[i]);
  }
  c.ans = ls.ans + rs.ans + chu(ls, rs, l, r, mid);
  return c;
}
void change(long long ts, long long v, long long l) {
  tr[ts].ans = (v >= x);
  for (long long i = 0; i < B; i++) {
    long long k = v >> i & 1;
    if (k)
      tr[ts].la[i] = l, tr[ts].ra[i] = l;
    else
      tr[ts].la[i] = inf, tr[ts].ra[i] = 0;
  }
}
void build(long long ts, long long l, long long r) {
  if (l == r) {
    change(ts, a[l], l);
    return;
  }
  long long mid = (l + r) >> 1;
  build(ts << 1, l, mid);
  build(ts << 1 | 1, mid + 1, r);
  tr[ts] = pushup(tr[ts << 1], tr[ts << 1 | 1], l, r, mid);
}
void update(long long ts, long long l, long long r, long long k, long long v) {
  if (l == r) {
    change(ts, v, l);
    return;
  }
  long long mid = (l + r) >> 1;
  if (k <= mid)
    update(ts << 1, l, mid, k, v);
  else
    update(ts << 1 | 1, mid + 1, r, k, v);
  tr[ts] = pushup(tr[ts << 1], tr[ts << 1 | 1], l, r, mid);
}
tree query(long long ts, long long l, long long r, long long L, long long R) {
  if (l == L && r == R) return tr[ts];
  long long mid = (l + r) >> 1;
  if (R <= mid)
    return query(ts << 1, l, mid, L, R);
  else if (L > mid)
    return query(ts << 1 | 1, mid + 1, r, L, R);
  else
    return pushup(query(ts << 1, l, mid, L, mid),
                  query(ts << 1 | 1, mid + 1, r, mid + 1, R), L, R, mid);
}
signed main() {
  n = read(), m = read(), x = read();
  for (long long i = 1; i <= n; i++) a[i] = read();
  build(1, 1, n);
  for (long long i = 1, opt, l, r; i <= m; i++) {
    opt = read(), l = read(), r = read();
    if (opt == 1)
      a[l] = r, update(1, 1, n, l, r);
    else {
      writeln(query(1, 1, n, l, r).ans);
    }
  }
}
