#include <bits/stdc++.h>
using namespace std;
char buf[25];
const int maxn = 100010;
struct tree {
  int l, r, lc, rc;
  long long ans;
} t[maxn * 2];
vector<pair<int, int>> vl[maxn * 2], vr[maxn * 2];
int a[maxn];
int n, m, val, rt, num;
int read() {
  int x = 0, f = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = 1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return f ? -x : x;
}
void write(long long x) {
  if (!x) {
    putchar('0');
    return;
  }
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  int cnt = 0;
  while (x) {
    buf[++cnt] = '0' + x % 10;
    x /= 10;
  }
  for (int i = cnt; i >= 1; --i) putchar(buf[i]);
}
long long cacl(int x, int l, int r) {
  int mid = (t[x].l + t[x].r) / 2;
  if (l > mid || r < mid + 1) return 0;
  int lc = t[x].lc, rc = t[x].rc;
  int w = vr[lc].size() - 1;
  long long ans = 0;
  while (w && vr[lc][w].first < l) --w;
  for (int i = 0; i < vl[rc].size() && vl[rc][i].first <= r; ++i) {
    while (w && (vr[lc][w - 1].second | vl[rc][i].second) >= val) --w;
    if ((vr[lc][w].second | vl[rc][i].second) >= val)
      if (i != vl[rc].size() - 1 && vl[rc][i + 1].first <= r)
        ans += 1ll * (vr[lc][w].first - l + 1) *
               (vl[rc][i + 1].first - vl[rc][i].first);
      else
        ans += 1ll * (vr[lc][w].first - l + 1) * (r - vl[rc][i].first + 1);
  }
  return ans;
}
void updata(int x) {
  int lc = t[x].lc, rc = t[x].rc, tmp;
  vl[x] = vl[lc];
  tmp = vl[lc][vl[lc].size() - 1].second;
  for (int i = 0; i < vl[rc].size(); ++i)
    if ((a[vl[rc][i].first] | tmp) != tmp) {
      tmp |= a[vl[rc][i].first];
      vl[x].push_back(make_pair(vl[rc][i].first, tmp));
    }
  vr[x] = vr[rc];
  tmp = vr[rc][vr[rc].size() - 1].second;
  for (int i = 0; i < vr[lc].size(); ++i)
    if ((a[vr[lc][i].first] | tmp) != tmp) {
      tmp |= a[vr[lc][i].first];
      vr[x].push_back(make_pair(vr[lc][i].first, tmp));
    }
  t[x].ans = t[lc].ans + t[rc].ans + cacl(x, t[x].l, t[x].r);
}
int build(int l, int r) {
  int x = ++num;
  t[x].l = l;
  t[x].r = r;
  if (l == r) {
    t[x].ans = (a[l] >= val);
    vl[x].push_back(make_pair(l, a[l]));
    vr[x].push_back(make_pair(r, a[r]));
  } else {
    int mid = (l + r) / 2;
    t[x].lc = build(l, mid);
    t[x].rc = build(mid + 1, r);
    updata(x);
  }
  return x;
}
void change(int x, int w) {
  if (t[x].l == t[x].r) {
    vl[x][0] = make_pair(w, a[w]);
    vr[x][0] = make_pair(w, a[w]);
    t[x].ans = (a[w] >= val);
    return;
  }
  int mid = (t[x].l + t[x].r) / 2;
  if (w <= mid)
    change(t[x].lc, w);
  else
    change(t[x].rc, w);
  updata(x);
}
long long query(int x, int l, int r) {
  if (r < t[x].l || t[x].r < l) return 0;
  if (l <= t[x].l && t[x].r <= r) return t[x].ans;
  return query(t[x].lc, l, r) + query(t[x].rc, l, r) +
         cacl(x, max(t[x].l, l), min(t[x].r, r));
}
int main() {
  n = read();
  m = read();
  val = read();
  for (int i = 1; i <= n; ++i) a[i] = read();
  rt = build(1, n);
  for (int i = 1; i <= m; ++i) {
    int opt = read();
    if (opt == 1) {
      int x = read(), y = read();
      a[x] = y;
      change(rt, x);
    } else {
      int x = read(), y = read();
      write(query(rt, x, y));
      putchar('\n');
    }
  }
  return 0;
}
