#include <bits/stdc++.h>
int n, m, p;
using namespace std;
struct Tree {
  long long sum;
  vector<pair<int, int>> left, right;
} t[400010];
int getmin(int a, int b) {
  if (a > b) return b;
  return a;
}
int getmax(int a, int b) {
  if (a > b) return a;
  return b;
}
void Update(int x, int nl, int nr) {
  int temp, j;
  t[x].sum = t[x * 2].sum + t[x * 2 + 1].sum;
  j = 0;
  for (int i = t[x * 2].left.size() - 1; i >= 0; --i) {
    while (j < t[x * 2 + 1].right.size() &&
           (t[x * 2 + 1].right[j].first | t[x * 2].left[i].first) < p)
      ++j;
    if (j == t[x * 2 + 1].right.size()) break;
    temp = t[x * 2].left[i].second;
    if (i == t[x * 2].left.size() - 1)
      temp -= nl - 1;
    else
      temp -= t[x * 2].left[i + 1].second;
    t[x].sum += 1LL * temp * (nr - t[x * 2 + 1].right[j].second + 1);
  }
  t[x].left = t[x * 2 + 1].left;
  temp = t[x].left[t[x].left.size() - 1].first;
  for (int i = 0; i < t[x * 2].left.size(); ++i) {
    if ((t[x * 2].left[i].first | temp) > temp) {
      temp = t[x * 2].left[i].first | temp;
      t[x].left.push_back({temp, t[x * 2].left[i].second});
    }
  }
  t[x].right = t[x * 2].right;
  temp = t[x].right[t[x].right.size() - 1].first;
  for (int i = 0; i < t[x * 2 + 1].right.size(); ++i) {
    if ((t[x * 2 + 1].right[i].first | temp) > temp) {
      temp = t[x * 2 + 1].right[i].first | temp;
      t[x].right.push_back({temp, t[x * 2 + 1].right[i].second});
    }
  }
}
void Insert(int x, int nl, int nr, int aim, int y, int partial) {
  if (nl == nr) {
    t[x].left.clear();
    t[x].right.clear();
    t[x].left.push_back({y, aim});
    t[x].right.push_back({y, aim});
    t[x].sum = (y >= p);
    return;
  }
  int mid = (nl + nr) / 2;
  if (aim <= mid)
    Insert(x * 2, nl, mid, aim, y, partial);
  else
    Insert(x * 2 + 1, mid + 1, nr, aim, y, partial);
  if (!partial || (aim == nr)) Update(x, nl, nr);
}
long long Answer(int x, int nl, int nr, int al, int ar) {
  if (nl == al && nr == ar) return t[x].sum;
  int mid = (nl + nr) / 2;
  long long re = 0;
  if (al <= mid) re += Answer(x * 2, nl, mid, al, getmin(mid, ar));
  if (ar > mid) re += Answer(x * 2 + 1, mid + 1, nr, getmax(al, mid + 1), ar);
  int temp, j;
  j = 0;
  for (int i = t[x * 2].left.size() - 1; i >= 0; --i) {
    if (t[x * 2].left[i].second < al) continue;
    while (j < t[x * 2 + 1].right.size() &&
           (t[x * 2 + 1].right[j].first | t[x * 2].left[i].first) < p)
      ++j;
    if (j == t[x * 2 + 1].right.size() || t[x * 2 + 1].right[j].second > ar)
      break;
    temp = t[x * 2].left[i].second;
    if (i == t[x * 2].left.size() - 1 || t[x * 2].left[i + 1].second < al)
      temp -= al - 1;
    else
      temp -= t[x * 2].left[i + 1].second;
    re += 1LL * temp * (ar - t[x * 2 + 1].right[j].second + 1);
  }
  return re;
}
int main() {
  scanf("%d %d %d", &n, &m, &p);
  int a, b, c;
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &c);
    Insert(1, 1, n, i, c, 1);
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d %d %d", &a, &b, &c);
    if (a == 1)
      Insert(1, 1, n, b, c, 0);
    else
      printf("%I64d\n", Answer(1, 1, n, b, c));
  }
  return 0;
}
