#include <bits/stdc++.h>
using namespace std;
int const M = 2e5 + 10, M2 = 1000 + 10, inf = 1e9 + 10, mod = 1e9 + 7;
int n, q, x, a[M], l[M], r[M], ty[M], lazy[M * 4], mn[M * 4];
long long seg[M * 4];
set<int> dig[30];
set<int>::iterator it;
void add1(int x, int ind) {
  for (int i = 0; i <= 20; i++) {
    if ((x & (1 << i))) dig[i].insert(ind);
  }
}
void del1(int x, int ind) {
  for (int i = 0; i <= 20; i++) {
    if ((x & (1 << i))) dig[i].erase(ind);
  }
}
void shift(int node, int l, int r, int mid) {
  if (lazy[node] == -1) return;
  long long t = (long long)lazy[node];
  seg[node * 2] = (long long)(mid - l) * t;
  seg[node * 2 + 1] = (long long)(r - mid) * t;
  lazy[node * 2] = t;
  lazy[node * 2 + 1] = t;
  mn[node * 2] = t;
  mn[node * 2 + 1] = t;
  lazy[node] = -1;
}
int bin(int l, int r, int len, int node) {
  if (r - l == 1) {
    if (mn[node] > len) return n + 1;
    return l;
  }
  int mid = (l + r) >> 1;
  shift(node, l, r, mid);
  if (mn[node * 2] <= len) return bin(l, mid, len, node * 2);
  return bin(mid, r, len, node * 2 + 1);
}
void upd(int l, int r, int st, int en, int inc, int node) {
  if (st <= l && r <= en) {
    seg[node] = (long long)inc * (long long)(r - l);
    mn[node] = inc;
    lazy[node] = inc;
    return;
  }
  if (st >= r || l >= en) return;
  int mid = (l + r) >> 1;
  shift(node, l, r, mid);
  upd(l, mid, st, en, inc, node * 2);
  upd(mid, r, st, en, inc, node * 2 + 1);
  seg[node] = seg[node * 2] + seg[node * 2 + 1];
  mn[node] = min(mn[node * 2], mn[node * 2 + 1]);
}
long long get(int l, int r, int st, int en, int node) {
  if (st <= l && r <= en) return seg[node];
  if (st >= r || l >= en) return 0;
  int mid = (l + r) >> 1;
  shift(node, l, r, mid);
  return get(l, mid, st, en, node * 2) + get(mid, r, st, en, node * 2 + 1);
}
void ch(int ind) {
  int len = n - ind + 1;
  int f = bin(1, n + 1, len, 1);
  vector<pair<int, int> > d;
  for (int i = 0; i <= 20; i++) {
    it = dig[i].lower_bound(ind);
    int en = *it;
    if (en < f) continue;
    d.push_back(make_pair(en, i));
    it--;
    en = *it;
    if (en < f) continue;
    d.push_back(make_pair(en, i));
  }
  d.push_back(make_pair(ind, -1));
  sort(d.begin(), d.end());
  for (int i = 0; i < d.size(); i++) {
    if (d[i].first > ind) break;
    int now = 0, good = n + 1;
    for (int j = i; j < d.size(); j++) {
      if (d[j].second != -1) now |= (1 << d[j].second);
      if (now >= x) {
        good = d[j].first;
        break;
      }
    }
    int lst = f;
    if (i != 0) lst = d[i - 1].first + 1;
    upd(1, n + 1, lst, d[i].first + 1, n + 1 - good, 1);
  }
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> q >> x;
  for (int i = 1; i < 4 * M - 2; i++) lazy[i] = -1;
  for (int i = 0; i <= 20; i++) dig[i].insert(0), dig[i].insert(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    add1(a[i], i);
    ch(i);
  }
  for (int i = 1; i <= q; i++) {
    int ty;
    cin >> ty;
    if (ty == 1) {
      int ind, x;
      cin >> ind >> x;
      del1(a[ind], ind);
      a[ind] = x;
      add1(a[ind], ind);
      ch(ind);
    } else {
      int l, r;
      cin >> l >> r;
      int tmp = n - r;
      int f = bin(1, n + 1, tmp, 1);
      if (f <= l) {
        cout << 0 << "\n";
        continue;
      }
      cout << get(1, n + 1, l, f, 1) -
                  (long long)((long long)tmp * (long long)(f - l))
           << "\n";
    }
  }
}
