#include <bits/stdc++.h>
using namespace std;
int n, m, X;
int a[100005];
long long ans;
struct Data {
  int l, r;
  long long sum;
  pair<int, int> left[21], right[21];
  void init(int pos, int val) {
    l = r = pos;
    left[0] = {pos, val};
    right[0] = {pos, val};
    left[1] = {pos + 1, val};
    right[1] = {pos - 1, val};
    sum = (val >= X);
  }
  void unite(Data &leftSide, Data &rightSide) {
    l = leftSide.l;
    r = rightSide.r;
    for (int i = 0; i < 21; i++) {
      left[i] = leftSide.left[i];
      if (left[i].first == rightSide.l) {
        if (i < 21 - 1) {
          for (int j = 0; rightSide.left[j].first <= r; j++) {
            if ((left[i - 1].second | rightSide.left[j].second) >
                left[i - 1].second) {
              left[i].first = rightSide.left[j].first;
              left[i].second = left[i - 1].second | rightSide.left[j].second;
              i++;
            }
          }
        }
        left[i].first = r + 1;
        break;
      }
    }
    for (int i = 0; i < 21; i++) {
      right[i] = rightSide.right[i];
      if (right[i].first == leftSide.r) {
        if (i < 21 - 1) {
          for (int j = 0; leftSide.right[j].first >= l; j++) {
            if ((right[i - 1].second | leftSide.right[j].second) >
                right[i - 1].second) {
              right[i].first = leftSide.right[j].first;
              right[i].second = right[i - 1].second | leftSide.right[j].second;
              i++;
            }
          }
        }
        right[i].first = l - 1;
        break;
      }
    }
    sum = leftSide.sum + rightSide.sum;
    int j = 0;
    while (rightSide.left[j].first <= r) {
      j++;
    }
    for (int i = 0; leftSide.right[i].first >= l; i++) {
      while (j > 0 &&
             (leftSide.right[i].second | rightSide.left[j - 1].second) >= X) {
        j--;
      }
      if (rightSide.left[j].first <= r) {
        sum += 1LL * (r - rightSide.left[j].first + 1) *
               (leftSide.right[i].first - leftSide.right[i + 1].first);
      }
    }
  }
} tree[100005 << 2];
void initTree(int l, int r, int i) {
  if (l == r) {
    tree[i].init(l, a[l]);
  } else {
    int mid = (l + r) >> 1;
    initTree(l, mid, i + i);
    initTree(mid + 1, r, i + i + 1);
    tree[i].unite(tree[i + i], tree[i + i + 1]);
  }
}
void modify(int l, int r, int p, int i) {
  if (l == r) {
    tree[i].init(l, a[l]);
  } else {
    int mid = (l + r) >> 1;
    if (mid >= p) {
      modify(l, mid, p, i + i);
    } else {
      modify(mid + 1, r, p, i + i + 1);
    }
    tree[i].unite(tree[i + i], tree[i + i + 1]);
  }
}
Data calc(int l, int r, int x, int y, int i) {
  if (x <= l && r <= y) {
    return tree[i];
  } else {
    int mid = (l + r) >> 1;
    if (mid >= y) {
      return calc(l, mid, x, y, i + i);
    }
    if (mid < x) {
      return calc(mid + 1, r, x, y, i + i + 1);
    }
    Data ret;
    Data leftSide = calc(l, mid, x, y, i + i);
    Data rightSide = calc(mid + 1, r, x, y, i + i + 1);
    ret.unite(leftSide, rightSide);
    return ret;
  }
}
int main() {
  scanf("%d %d %d", &n, &m, &X);
  for (int i = 1; i <= n; i++) {
    scanf("%d", a + i);
  }
  initTree(1, n, 1);
  for (int i = 0; i < m; i++) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int p, v;
      scanf("%d %d", &p, &v);
      a[p] = v;
      modify(1, n, p, 1);
    } else {
      int l, r;
      scanf("%d %d", &l, &r);
      printf("%lld\n", calc(1, n, l, r, 1).sum);
    }
  }
}
