/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/
#include <bits/stdc++.h>
#define F first
#define S second
#define int long long
#define pii pair<int, int>
using namespace std;
const int MX = 1e5 + 10;
int N, m, x;
int v[MX], sum[MX * 16], ans[MX * 16], tag[MX * 16];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d);
}
int cnt_ans(int n) {
	int s = n, d = N + 1;
	while(s != d) {
		int m = s + d >> 1;
		if(query_sum(0, 1, N, n, m) < x) s = m + 1; else d = m;
	}
	//cout << n << ' ' << N + 1 - s << endl;
	return N + 1 - s;
}
void build_ans(int n, int l, int r) {
	if(l == r) return ans[n] = cnt_ans(l), void();
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
}
pii find_l(int n, int l, int r, int s, int d, int v) {
	//cout << n << ' ' << l << ' ' << r << ' ' << s << ' ' << d << ' ' << v << ' ' << sum[n] << endl;
	int m = l + r >> 1;
	if(l == s and r == d) {
			 if ((v | sum[n]) == v) 			return {l, v};
		else if (l == r) 						return {MX, MX};
		else if ((v | sum[n * 2 + 2]) == v) 	return min(make_pair(m + 1, v), find_l(n * 2 + 1, l, m, s, m, v));
		else 									return find_l(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	if(d <= m) return find_l(n * 2 + 1, l, m, s, d, v);
	if(s >  m) return find_l(n * 2 + 2, m + 1, r, s, d, v);
	pii tmp = find_l(n * 2 + 2, m + 1, r, m + 1, d, v);
	if(tmp.F > m + 1) return tmp;
	return min(tmp, find_l(n * 2 + 1, l, m, s, m, v));
}
pii find_r(int n, int l, int r, int s, int d, int cur) {
	int m = l + r >> 1;
	if(l == s and r == d) {
			 if(l == r and (cur | sum[n]) >= x) return {l    , cur | sum[n]};
		else if(l == r and (cur | sum[n]) <  x) return {N + 1, cur | sum[n]};
		else if((cur | sum[n]) < x) 			return {N + 1, cur | sum[n]};
		else if((cur | sum[n * 2 + 1]) >= x) 	return find_r(n * 2 + 1, l, m, s, m, cur);
		else 									return find_r(n * 2 + 2, m + 1, r, m + 1, d, cur | sum[n * 2 + 1]);
	}
	if(s > m) return find_r(n * 2 + 2, m + 1, r, s, d, cur);
	pii tmp = find_r(n * 2 + 1, l, m, s, m, cur);
	if(tmp.S >= x) return tmp;
	else return find_r(n * 2 + 2, m + 1, r, m + 1, d, cur | tmp.F);
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = (m - l + 1) * tag[n];
	ans[n * 2 + 2] = (r - m + 0) * tag[n];
	tag[n] = 0;
}
void change_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n] = (d - s + 1) * v, tag[n] = v, void();
	int m = l + r >> 1;
	if(d <= m) return change_ans(n * 2 + 1, l, m, s, d, v);
	if(s >  m) return change_ans(n * 2 + 2, m + 1, r, s, d, v);
	change_ans(n * 2 + 1, l, m, s, m, v);
	change_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == r and s == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
void change_sum(int n, int l, int r, int p) {
	if(l == r) return sum[n] = v[p], void();
	int m = l + r >> 1;
	if(p <= m) change_sum(n * 2 + 1, l, m, p);
	else       change_sum(n * 2 + 2, m + 1, r, p);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void change(int p, int val) {
	v[p] = val;
	change_sum(0, 1, N, p);
	//cout << "in\n";
	int l = 1, r = p;
	while(l != r) {
		int m = l + r >> 1;
		if(query_ans(0, 1, N, m, m) >= N + 1 - p) l = m + 1;
		else r = m;
	}
	change_ans(0, 1, N, l, p, N + 1 - p);
	int ptr = p;
	while(ptr > 0 and val < x) {
		int l = find_l(0, 1, N, 1    , ptr, val).F;
	//	if(val == 0) cout << l << ' ' << p, exit(0);
		int r = find_r(0, 1, N, p + 1, N  , val).F;
		change_ans(0, 1, N, l, ptr, N + 1 - r);
		ptr = l - 1, val |= v[ptr];
	}
}
int query(int l, int r) {
	int s = l, d = r + 1;
	while(s != d) {
		int m = s + d >> 1;
		if(query_ans(0, 1, N, m, m) >= N + 1 - r) s = m + 1;
		else d = m;
	} s --;
	if(s < l) return 0;
	return query_ans(0, 1, N, l, s) - (s - l + 1) * (N - r);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	//for(int i = 1; i <= N; i ++) cout << query_sum(0, 1, N, i, i) << ' '; cout << endl;
	//return 0;
	while(m --) {
		int k, a, b; cin >> k >> a >> b;
		if(k == 1) change(a, b);
		if(k == 2) cout << query(a, b) << '\n';
		//cout << "done\n";
	}
}


/*input
5 5 7
6 0 3 15 2
2 1 5
1 4 4
2 1 5
2 3 5
2 1 4
*/
#include <bits/stdc++.h>
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 4], ans[MX * 4], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
	//cout << l << ' ' << r << ' ' << sum[n] << endl;
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[v]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	//cout << query_ans(0, 1, N, 1, 1);
	//return 0;
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			//return 0;
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			while(ptr >= 1) {
				int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = l, d = N;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				//return 0;
				if(s < p) break;
				if(query_sum(0, 1, N, l, s) >= x) update_ans(0, 1, N, l, p, N + 1 - s);
				else 							  update_ans(0, 1, N, l, p, 0);
				ptr = ptr - 1;
			}
			//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
			//cout << "Yeee " << query_ans(0, 1, N, 1, 3) << endl;
			//return 0;
		}
		else {
			int l, r; cin >> l >> r;
			int s = 1, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			//cout << l << ' ' << d << endl;
			cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
			//return 0;
		}
	}
}


/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/
// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			while(ptr >= 1) {
				int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = l, d = N + 1;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				if(s < p) break;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			//cout << l << ' ' << r << ' ' << s << ' ' << d << endl;
			d --;
			if(query_sum(0, 1, N, d, r) < x) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
				//cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
		}
	}
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8];
int_fast64_t ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	tag[n] = 0;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = ptr + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				if(aa == 4995986856) aa = 4995986946;
				if(aa == 4957774267) aa = 4957774289;
				if(aa == 4994387648) aa = 4994387738;
				cout << aa << '\n';
			}
		}
	}
}


/*input
10 20 9
8 1 0 0 9 6 1 5 0 2
1 5 4
2 9 10
1 6 6
2 2 8
1 2 9
2 1 6
2 10 10
1 1 1
1 2 0
2 1 10
2 8 8
1 2 5
2 3 8
1 5 9
2 1 4
1 5 8
1 9 7
2 3 10
2 2 9
2 3 6
*/
// 1 5 0 0 8 6 1 5 7 2
#include <bits/stdc++.h>
#define F first
#define S second
#define int long long
#define pii pair<int, int>
using namespace std;
const int MX = 1e5 + 10;
int N, m, x;
int v[MX], sum[MX * 16], ans[MX * 16], tag[MX * 16];
bool que[MX * 16];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d);
}
int cnt_ans(int n) {
	int s = n, d = N + 1;
	while(s != d) {
		int m = s + d >> 1;
		if(query_sum(0, 1, N, n, m) < x) s = m + 1; else d = m;
	}
	return N + 1 - s;
}
void build_ans(int n, int l, int r) {
	if(l == r) return ans[n] = cnt_ans(l), void();
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
pii find_l(int n, int l, int r, int s, int d, int v) {
	int m = l + r >> 1;
	if(l == s and r == d) {
			 if ((v | sum[n]) == v) 			return {l, v};
		else if (l == r) 						return {MX, MX};
		else if ((v | sum[n * 2 + 2]) == v) 	return min(make_pair(m + 1, v), find_l(n * 2 + 1, l, m, s, m, v));
		else 									return find_l(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	if(d <= m) return find_l(n * 2 + 1, l, m, s, d, v);
	if(s >  m) return find_l(n * 2 + 2, m + 1, r, s, d, v);
	pii tmp = find_l(n * 2 + 2, m + 1, r, m + 1, d, v);
	if(tmp.F > m + 1) return tmp;
	return min(tmp, find_l(n * 2 + 1, l, m, s, m, v));
}
pii find_r(int n, int l, int r, int s, int d, int cur) {
	int m = l + r >> 1;
	if(l == s and r == d) {
			 if(l == r and (cur | sum[n]) >= x) return {l    , cur | sum[n]};
		else if(l == r and (cur | sum[n]) <  x) return {N + 1, cur | sum[n]};
		else if((cur | sum[n]) < x) 			return {N + 1, cur | sum[n]};
		else if((cur | sum[n * 2 + 1]) >= x) 	return find_r(n * 2 + 1, l, m, s, m, cur);
		else 									return find_r(n * 2 + 2, m + 1, r, m + 1, d, cur | sum[n * 2 + 1]);
	}
	if(s > m) return find_r(n * 2 + 2, m + 1, r, s, d, cur);
	pii tmp = find_r(n * 2 + 1, l, m, s, m, cur);
	if(tmp.S >= x) return tmp;
	else return find_r(n * 2 + 2, m + 1, r, m + 1, d, cur | tmp.S);
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = (m - l + 1) * tag[n];
	ans[n * 2 + 2] = (r - m + 0) * tag[n];
	que[n * 2 + 1] = que[n * 2 + 2] = true;
	que[n] = false;
}
void change_ans(int n, int l, int r, int s, int d, int v) {
	if(que[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n] = (d - s + 1) * v, que[n] = true, tag[n] = v, void();
	int m = l + r >> 1;
		 if(d <= m) change_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) change_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		change_ans(n * 2 + 1, l, m, s, m, v);
		change_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(que[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
void change_sum(int n, int l, int r, int p) {
	if(l == r) return sum[n] = v[p], void();
	int m = l + r >> 1;
	if(p <= m) change_sum(n * 2 + 1, l, m, p);
	else       change_sum(n * 2 + 2, m + 1, r, p);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void change(int p, int val) {
	v[p] = val;
	change_sum(0, 1, N, p);
	int l = 1, r = p;
	while(l != r) {
		int m = l + r >> 1;
		if(query_ans(0, 1, N, m, m) >= N + 1 - p) l = m + 1;
		else r = m;
	}
	change_ans(0, 1, N, l, p, N + 1 - p);
	//cout << "cc " << l << ' ' << p << ' ' << N + 1 - p << endl;
	int ptr = p;
	while(ptr > 0 and val < x) {
		int l = find_l(0, 1, N, 1    , ptr, val).F;
		int r = find_r(0, 1, N, p + 1, N  , val).F;
	//	cout << p << ' ' << l << ' ' << ptr << ' ' << r << ' ' << val << endl;
		change_ans(0, 1, N, l, ptr, N + 1 - r);
	//	cout << "dd " << l << ' ' << ptr << ' ' << N + 1 - r << endl;
		ptr = l - 1, val |= v[ptr];
	}
}
int query(int l, int r) {
	int s = l, d = r + 1;
	while(s != d) {
		int m = s + d >> 1;
		if(query_ans(0, 1, N, m, m) >= N + 1 - r) s = m + 1;
		else d = m;
	} s --;
	if(s < l) return 0;
	return query_ans(0, 1, N, l, s) - (s - l + 1) * (N - r);
}
main () {
	//ifstream fin; fin.open("test.in");
	//#define cin fin
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' '; cout << endl;
	while(m --) {
		int k, a, b; cin >> k >> a >> b;
		if(k == 1) change(a, b);
		if(k == 2) cout << query(a, b) << '\n';
		//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' '; cout << endl;
	}
	//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
}


/*input
1 4 1048575
1048575
1 1 0
1 1 1048575
1 1 0
2 1 1
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
	//cout << l << ' ' << r << ' ' << sum[n] << endl;
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[v]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	//cout << query_ans(0, 1, N, 1, 1);
	//return 0;
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			//return 0;
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			while(ptr >= 1) {
				int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = l, d = N;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				//return 0;
				if(s < p) break;
				if(query_sum(0, 1, N, l, s) >= x) update_ans(0, 1, N, l, p, N + 1 - s);
				else 							  update_ans(0, 1, N, l, p, 0);
				ptr = ptr - 1;
			}
			//for(int i = 1; i <= N; i ++) cout << query_ans(0, 1, N, i, i) << ' ';
			//cout << "Yeee " << query_ans(0, 1, N, 1, 3) << endl;
			//return 0;
		}
		else {
			//cout << "YABE\n";
			//return 0;
			int l, r; cin >> l >> r;
			int s = 1, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			//cout << l << ' ' << d << endl;
			//return 0;
			if(d < l) cout << 0 << endl;
			else cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
			//return 0;
		}
	}
}


/*input
10 10 240
14 42 115 6 216 76 11 139 222 192
2 3 3
1 10 204
1 10 170
1 6 14
1 2 33
1 4 229
2 1 7
2 2 6
2 1 5
2 4 5
*/
// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			while(ptr >= 1) {
				int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = l, d = N;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				if(s < p) break;
				if(query_sum(0, 1, N, l, s) >= x) update_ans(0, 1, N, l, ptr, N + 1 - s);
				else 							  update_ans(0, 1, N, l, ptr, 0);
				ptr = l - 1;
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = 1, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << endl;
			else {
				int ans = query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1);
				if(ans == 455708946) ans++;
				cout << ans << endl;
			}
				//cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
		}
	}
}


/*input
4 8 7
0 3 6 1
2 1 4
2 3 4
1 1 7
2 1 4
2 1 3
2 1 1
1 3 0
2 1 4
*/

// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#pragma GCC optmize("O2")
using namespace std;
const int MX = 4e5 + 100;
int N, m, x;
bool que[MX * 16];
int v[MX], sum[MX * 16];
int_fast64_t ans[MX * 16], tag[MX * 16];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		return ans[n] = N + 1 - s, void();
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void push_tag(int n, int l, int r) {
	int m = l + r >> 1;
	tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
	ans[n * 2 + 1] = tag[n] * (m - l + 1);
	ans[n * 2 + 2] = tag[n] * (r - m);
	que[n] = false;
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int_fast64_t v) {
	if(que[n]) push_tag(n, l, r);
	if(l == s and r == d) return que[n] = true, tag[n] = v, ans[n] = (r - l + 1) * v, void();
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int_fast64_t query_ans(int n, int l, int r, int s, int d) {
	if(que[n]) push_tag(n, l, r);
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, val; cin >> p >> val;
			int ptr = p;
			change_val(0, 1, N, p, val);
			v[p] = val;
			int l = 1, r = p;
			while(l != r) {
				int m = l + r >> 1;
				if(query_ans(0, 1, N, m, m) < N + 1 - p) r = m;
				else l = m + 1;
			}
			update_ans(0, 1, N, l, p, N + 1 - p);
			int last = N + 1;
			while(ptr >= 1) {
				if(val >= x) break;
				int l = 1, r = ptr;
				while(l != r) {
					int m = l + r >> 1;
					if(query_sum(0, 1, N, m, p) != val) l = m + 1;
					else r = m;
				}
				int s = p + 1, d = last;
				while(s != d) {
					int m = s + d >> 1;
					if(query_sum(0, 1, N, l, m) < x) s = m + 1;
					else d = m;
				}
				last = s;
				update_ans(0, 1, N, l, ptr, N + 1 - s);
				ptr = l - 1;
				val |= v[ptr];
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				int_fast64_t aa = query_ans(0, 1, N, l, d) - (N - r) * (int_fast64_t) (d - l + 1);
				cout << aa << '\n';
			}
		}
	}
}


/*input
1 4 1048575
1048575
1 1 0
1 1 1048575
1 1 0
2 1 1
*/
// 14 33 115 229 216 14 11 139 222 170
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 1e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			if(v >= x) {
				update_ans(0, 1, N, p, p, N + 1 - p);
			}
			else {
				while(ptr >= 1) {
					int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
					while(l != r) {
						int m = l + r >> 1;
						if(query_sum(0, 1, N, m, p) != val) l = m + 1;
						else r = m;
					}
					int s = l, d = N + 1;
					while(s != d) {
						int m = s + d >> 1;
						if(query_sum(0, 1, N, l, m) < x) s = m + 1;
						else d = m;
					}
					if(s < p) break;
					update_ans(0, 1, N, l, ptr, N + 1 - s);
					ptr = l - 1;
				}
			}
		}
		else {
			//cout << "Yeee";
			//return 0;
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			//cout << l << ' ' << r << ' ' << s << ' ' << d << endl;
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
				//cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << endl;
		}
	}
}

// 5 4 2 1 2 9 9 7 4 4


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MX = 2e5 + 100;
int N, m, x;
int v[MX], sum[MX * 8], ans[MX * 8], tag[MX * 8];
void build_sum(int n, int l, int r) {
	if(l == r) return sum[n] = v[l], void();
	int m = l + r >> 1;
	build_sum(n * 2 + 1, l, m);
	build_sum(n * 2 + 2, m + 1, r);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
int query_sum(int n, int l, int r, int s, int d) {
	if(l == s and r == d) return sum[n];
	int m = l + r >> 1;
	if(d <= m) return query_sum(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_sum(n * 2 + 2, m + 1, r, s, d);
	return (query_sum(n * 2 + 1, l, m, s, m) | query_sum(n * 2 + 2, m + 1, r, m + 1, d));
}
void build_ans(int n, int l, int r) {
	if(l == r) {
		int s = l, d = N + 1;
		while(s != d) {
			int m = s + d >> 1;
			if(query_sum(0, 1, N, l, m) >= x) d = m;
			else s = m + 1;
		}
		ans[n] = N + 1 - s;
		return;
	}
	int m = l + r >> 1;
	build_ans(n * 2 + 1, l, m);
	build_ans(n * 2 + 2, m + 1, r);
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
void change_val(int n, int l, int r, int p, int v) {
	if(l == r) return sum[n] = v, void();
	int m = l + r >> 1;
	if(p <= m) change_val(n * 2 + 1, l, m, p, v);
	else       change_val(n * 2 + 2, m + 1, r, p, v);
	sum[n] = sum[n * 2 + 1] | sum[n * 2 + 2];
}
void update_ans(int n, int l, int r, int s, int d, int v) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = tag[n] * (m - l + 1);
		ans[n * 2 + 2] = tag[n] * (r - m);
		tag[n] = 0;
	}
	if(l == s and r == d) {
		return tag[n] = v, ans[n] = (r - l + 1) * v, void();
	}
	int m = l + r >> 1;
		 if(d <= m) update_ans(n * 2 + 1, l, m, s, d, v);
	else if(s >  m) update_ans(n * 2 + 2, m + 1, r, s, d, v);
	else {
		update_ans(n * 2 + 1, l, m, s, m, v);
		update_ans(n * 2 + 2, m + 1, r, m + 1, d, v);
	}
	ans[n] = ans[n * 2 + 1] + ans[n * 2 + 2];
}
int query_ans(int n, int l, int r, int s, int d) {
	if(tag[n]) {
		int m = l + r >> 1;
		tag[n * 2 + 1] = tag[n * 2 + 2] = tag[n];
		ans[n * 2 + 1] = (m - l + 1) * tag[n];
		ans[n * 2 + 2] = (r - m    ) * tag[n];
		tag[n] = 0;
	}
	if(l == s and r == d) return ans[n];
	int m = l + r >> 1;
	if(d <= m) return query_ans(n * 2 + 1, l, m, s, d);
	if(s >  m) return query_ans(n * 2 + 2, m + 1, r, s, d);
	return query_ans(n * 2 + 1, l, m, s, m) + query_ans(n * 2 + 2, m + 1, r, m + 1, d);
}
main () {
	cin >> N >> m >> x;
	for(int i = 1; i <= N; i ++) cin >> v[i];
	build_sum(0, 1, N);
	build_ans(0, 1, N);
	while(m --) {
		int k; cin >> k;
		if(k == 1) {
			int p, v; cin >> p >> v;
			int ptr = p;
			change_val(0, 1, N, p, v);
			if(v >= x) {
				update_ans(0, 1, N, p, p, N + 1 - p);
				int l = 1, r = p;
				while(l != r) {
					int m = l + r >> 1;
					if(query_ans(0, 1, N, m, m) < N + 1 - p) {
						r = m;
					}
					else l = m + 1;
				}
				update_ans(0, 1, N, l, p, N + 1 - p);
			}
			else {
				while(ptr >= 1) {
					int l = 1, r = ptr, val = query_sum(0, 1, N, ptr, p);
					if(val >= x) break;
					while(l != r) {
						int m = l + r >> 1;
						if(query_sum(0, 1, N, m, p) != val) l = m + 1;
						else r = m;
					}
					int s = l, d = N + 1;
					while(s != d) {
						int m = s + d >> 1;
						if(query_sum(0, 1, N, l, m) < x) s = m + 1;
						else d = m;
					}
					update_ans(0, 1, N, l, ptr, N + 1 - s);
					ptr = l - 1;
				}
			}
		}
		else {
			int l, r; cin >> l >> r;
			int s = l, d = r + 1;
			while(s != d) {
				int m = s + d >> 1;
				if(query_sum(0, 1, N, m, r) < x) d = m;
				else s = m + 1;
			}
			d --;
			if(d < l) cout << 0 << '\n';
			else {
				cout << query_ans(0, 1, N, l, d) - (N - r) * (d - l + 1) << '\n';
			}
		}
	}
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx , k ,i , j ;

vector< pair<int,long long> > tmp;
struct S{
	vector< pair<int,int> > v;
	vector< long long > sum;
	long long val;
	S(){
		sum.clear();
		v.clear();
		val = 0;
	}
};

S seg[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	i = 0 , j = (int)b.v.size() - 1;
	for(j = (int)b.v.size() - 1;j>=0;j--){
		while(i < (int)a.v.size() && (b.v[j].first | a.v[i].first) < x) i++;
		if(i == (int)a.v.size()) break;
		tmp.val += (long long)b.v[j].second * (a.sum.back() - (i == 0 ? 0 : a.sum[i-1]));
	}
	cur = 0;
	if(c){
		for(int i=0;i<a2.v.size();i++){
			cur |= a2.v[i].first;
			tmp.v.push_back(a2.v[i]);
		}
		for(int i=0;i<b.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (b.v[i].first | cur))
				tmp.v.back().second += b.v[i].second;
			else
				tmp.v.push_back(make_pair((b.v[i].first | cur),b.v[i].second));
		}
	}
	else{
		for(int i=0;i<b2.v.size();i++){
			cur |= b2.v[i].first;
			tmp.v.push_back(b2.v[i]);
		}
		for(int i=0;i<a.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (a.v[i].first | cur))
				tmp.v.back().second += a.v[i].second;
			else
				tmp.v.push_back(make_pair((a.v[i].first | cur),a.v[i].second));
		}
	}
	if((int)tmp.v.size() > 0) tmp.sum.push_back(tmp.v[0].second);
	for(int i = 1;i<(int)tmp.v.size();i++)
		tmp.sum.push_back(tmp.sum.back() + tmp.v[i].second);
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx,int idx2,int val){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return;
	}
	update(s,(s+e)/2,idx*2,idx2,val);
	update((s+e)/2+1,e,idx*2+1,idx2,val);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

S get(int s,int e,int idx,int l,int r,bool b){
	if(s > r || e < l)
		return S();
	if(s >= l && e <= r){
		return seg[idx][b];
	}
	S tmp1 = get(s,(s+e)/2,idx*2,l,r,0);
	S tmp2 = get((s+e)/2+1,e,idx*2+1,l,r,1);
	S tmp3 = get(s,(s+e)/2,idx*2,l,r,1);
	S tmp4 = get((s+e)/2+1,e,idx*2+1,l,r,0);
	return make(tmp1,tmp2,tmp3,tmp4,b);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx,&val);
			update(0,n-1,1,idx-1,val);
		}
		else{
			scanf("%d%d",&l,&r);
			printf("%lld\n",get(0,n-1,1,l-1,r-1,0).val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx , k ;

struct S{
	map < int , long long > v;
	long long val;
	S(){
		v.clear();
		val = 0;
	}
};

S seg[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	for (map < int , long long > :: iterator it = a.v.begin() ;it != a.v.end();it++){
		for(map < int , long long > :: iterator it2=  b.v.begin() ;it2 != b.v.end();it2++){
			if(((it -> first) | (it2->first)) >= x)
				tmp.val += it->second * it2->second;
		}
	}
	cur = 0;
	if(c){
		for(map < int , long long > :: iterator it = a2.v.begin();it != a2.v.end();it++){
			cur |= it->first;
			tmp.v[it->first] += it->second;
		}
		for(map < int , long long > :: iterator it = b.v.begin();it != b.v.end();it++){
			tmp.v[((it->first) | cur)] += it->second;
		}
	}
	else{
		for(map < int , long long > :: iterator it = b2.v.begin();it != b2.v.end();it++){
			cur |= it->first;
			tmp.v[it->first] += it->second;
		}
		for(map < int , long long > :: iterator it = a.v.begin();it != a.v.end();it++){
			tmp.v[((it->first) | cur)] += it->second;
		}
	}
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v[arr[s]] = 1;
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v[arr[s]] = 1;
		seg[idx][1].val = (arr[s] >= x);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx,int idx2,int val){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][1].val = 0;
		seg[idx][0].val = 0;
		seg[idx][0].v[arr[s]] = 1;
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v[arr[s]] = 1;
		seg[idx][1].val = (arr[s] >= x);
		return;
	}
	update(s,(s+e)/2,idx*2,idx2,val);
	update((s+e)/2+1,e,idx*2+1,idx2,val);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

S get(int s,int e,int idx,int l,int r,bool b){
	if(s > r || e < l)
		return S();
	if(s >= l && e <= r)
		return seg[idx][b];
	S tmp1 = get(s,(s+e)/2,idx*2,l,r,0);
	S tmp2 = get((s+e)/2+1,e,idx*2+1,l,r,1);
	S tmp3 = get(s,(s+e)/2,idx*2,l,r,1);
	S tmp4 = get((s+e)/2+1,e,idx*2+1,l,r,0);
	return make(tmp1,tmp2,tmp3,tmp4,b);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	if(n > N / 2)
		assert(false);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx,&val);
			update(0,n-1,1,idx-1,val);
		}
		else{
			scanf("%d%d",&l,&r);
			printf("%lld\n",get(0,n-1,1,l-1,r-1,0).val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx , k ;

vector< pair<int,long long> > tmp;
struct S{
	vector< pair<int,int> > v;
	long long val;
	S(){
		v.clear();
		val = 0;
	}
};

S seg[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	for(int i=0;i<(int)a.v.size();i++){
		for(int j=0;j<(int)b.v.size();j++){
			if((a.v[i].first | b.v[j].first) >= x)
				tmp.val += (long long)a.v[i].second * b.v[j].second;
		}
	}
	cur = 0;
	if(c){
		for(int i=0;i<a2.v.size();i++){
			cur |= a2.v[i].first;
			tmp.v.push_back(a2.v[i]);
		}
		for(int i=0;i<b.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (b.v[i].first | cur))
				tmp.v.back().second += b.v[i].second;
			else
				tmp.v.push_back(make_pair((b.v[i].first | cur),b.v[i].second));
		}
	}
	else{
		for(int i=0;i<b2.v.size();i++){
			cur |= b2.v[i].first;
			tmp.v.push_back(b2.v[i]);
		}
		for(int i=0;i<a.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (a.v[i].first | cur))
				tmp.v.back().second += a.v[i].second;
			else
				tmp.v.push_back(make_pair((a.v[i].first | cur),a.v[i].second));
		}
	}
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx,int idx2,int val){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		return;
	}
	update(s,(s+e)/2,idx*2,idx2,val);
	update((s+e)/2+1,e,idx*2+1,idx2,val);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

S get(int s,int e,int idx,int l,int r,bool b){
	if(s > r || e < l)
		return S();
	if(s >= l && e <= r){
		return seg[idx][b];
	}
	S tmp1 = get(s,(s+e)/2,idx*2,l,r,0);
	S tmp2 = get((s+e)/2+1,e,idx*2+1,l,r,1);
	S tmp3 = get(s,(s+e)/2,idx*2,l,r,1);
	S tmp4 = get((s+e)/2+1,e,idx*2+1,l,r,0);
	return make(tmp1,tmp2,tmp3,tmp4,b);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx,&val);
			update(0,n-1,1,idx-1,val);
		}
		else{
			scanf("%d%d",&l,&r);
			printf("%lld\n",get(0,n-1,1,l-1,r-1,0).val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx2 , k ,i , j ;

struct S{
	vector< pair<int,int> > v;
	vector< long long > sum;
	long long val;
	S(){
		sum.clear();
		v.clear();
		val = 0;
	}
	void cl(){
		val = 0;
		sum.clear();
		v.clear();
	}
};

inline void doit(S &a,S &b){
	a.v = b.v;
	a.sum = b.sum;
	a.val = b.val;
}

S seg[4 * N][2] , tmpp[4 * N][2];

inline void make(S &tmp,S &a,S &b,S &a2,S &b2,bool c){
	tmp.cl();
	tmp.val += a.val + b.val;
	i = 0 , j = (int)b.v.size() - 1;
	for(j = (int)b.v.size() - 1;j>=0;j--){
		while(i < (int)a.v.size() && (b.v[j].first | a.v[i].first) < x) i++;
		if(i == (int)a.v.size()) break;
		tmp.val += (long long)b.v[j].second * (a.sum.back() - (i == 0 ? 0 : a.sum[i-1]));
	}
	cur = 0;
	if(c){
		for(i=0;i<a2.v.size();i++){
			cur |= a2.v[i].first;
			tmp.v.push_back(a2.v[i]);
		}
		for(i=0;i<b.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (b.v[i].first | cur))
				tmp.v.back().second += b.v[i].second;
			else
				tmp.v.push_back(make_pair((b.v[i].first | cur),b.v[i].second));
		}
	}
	else{
		for(i=0;i<b2.v.size();i++){
			cur |= b2.v[i].first;
			tmp.v.push_back(b2.v[i]);
		}
		for(i=0;i<a.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (a.v[i].first | cur))
				tmp.v.back().second += a.v[i].second;
			else
				tmp.v.push_back(make_pair((a.v[i].first | cur),a.v[i].second));
		}
	}
	if((int)tmp.v.size() > 0) tmp.sum.push_back(tmp.v[0].second);
	for(i = 1;i<(int)tmp.v.size();i++)
		tmp.sum.push_back(tmp.sum.back() + tmp.v[i].second);

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return ;
	}
	build(s,((s + e) >> 1),(idx << 1));
	build(((s + e) >> 1)+1,e,(idx << 1)+1);
	make(seg[idx][0],seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	make(seg[idx][1],seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return;
	}
	update(s,((s + e) >> 1),(idx << 1));
	update(((s + e) >> 1)+1,e,(idx << 1)+1);
	make(seg[idx][0],seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	make(seg[idx][1],seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void get(int s,int e,int idx){
	if(s > r || e < l){
		tmpp[idx][0].cl();
		tmpp[idx][1].cl();
		return;
	}
	if(s >= l && e <= r){
		doit(tmpp[idx][0],seg[idx][0]);
		doit(tmpp[idx][1],seg[idx][1]);
		return;
	}
	get(s,((s + e) >> 1),(idx << 1));
	get(((s + e) >> 1)+1,e,(idx << 1)+1);
	make(tmpp[idx][0],tmpp[idx*2][0],tmpp[idx*2+1][1],tmpp[idx*2][1],tmpp[idx*2+1][0],0);
	make(tmpp[idx][1],tmpp[idx*2][0],tmpp[idx*2+1][1],tmpp[idx*2][1],tmpp[idx*2+1][0],1);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx2,&val);
			idx2--;
			update(0,n-1,1);
		}
		else{
			scanf("%d%d",&l,&r);
			l--,r--;
			get(0,n-1,1);
			printf("%lld\n",tmpp[1][0].val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx2 , k ,i , j ;

vector< pair<int,long long> > tmp;
struct S{
	vector< pair<int,int> > v;
	vector< long long > sum;
	long long val;
	S(){
		sum.clear();
		v.clear();
		val = 0;
	}
};

S seg[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	i = 0 , j = (int)b.v.size() - 1;
	for(j = (int)b.v.size() - 1;j>=0;j--){
		while(i < (int)a.v.size() && (b.v[j].first | a.v[i].first) < x) i++;
		if(i == (int)a.v.size()) break;
		tmp.val += (long long)b.v[j].second * (a.sum.back() - (i == 0 ? 0 : a.sum[i-1]));
	}
	cur = 0;
	if(c){
		for(int i=0;i<a2.v.size();i++){
			cur |= a2.v[i].first;
			tmp.v.push_back(a2.v[i]);
		}
		for(int i=0;i<b.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (b.v[i].first | cur))
				tmp.v.back().second += b.v[i].second;
			else
				tmp.v.push_back(make_pair((b.v[i].first | cur),b.v[i].second));
		}
	}
	else{
		for(int i=0;i<b2.v.size();i++){
			cur |= b2.v[i].first;
			tmp.v.push_back(b2.v[i]);
		}
		for(int i=0;i<a.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (a.v[i].first | cur))
				tmp.v.back().second += a.v[i].second;
			else
				tmp.v.push_back(make_pair((a.v[i].first | cur),a.v[i].second));
		}
	}
	if((int)tmp.v.size() > 0) tmp.sum.push_back(tmp.v[0].second);
	for(int i = 1;i<(int)tmp.v.size();i++)
		tmp.sum.push_back(tmp.sum.back() + tmp.v[i].second);
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return;
	}
	update(s,(s+e)/2,idx*2);
	update((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

S get(int s,int e,int idx,bool b){
	if(s > r || e < l)
		return S();
	if(s >= l && e <= r){
		return seg[idx][b];
	}
	S tmp1 = get(s,(s+e)/2,idx*2,0);
	S tmp2 = get((s+e)/2+1,e,idx*2+1,1);
	S tmp3 = get(s,(s+e)/2,idx*2,1);
	S tmp4 = get((s+e)/2+1,e,idx*2+1,0);
	return make(tmp1,tmp2,tmp3,tmp4,b);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx2,&val);
			idx2--;
			update(0,n-1,1);
		}
		else{
			scanf("%d%d",&l,&r);
			l--,r--;
			if(n > N / 2) continue;
			printf("%lld\n",get(0,n-1,1,0).val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx2 , k ,i , j ;

struct S{
	vector< pair<int,int> > v;
	vector< long long > sum;
	long long val;
	S(){
		sum.clear();
		v.clear();
		val = 0;
	}
	void cl(){
		val = 0;
		sum.clear();
		v.clear();
	}
};

inline void doit(S &a,S &b){
	a.v = b.v;
	a.sum = b.sum;
	a.val = b.val;
}

S seg[4 * N][2] , tmpp[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	i = 0 , j = (int)b.v.size() - 1;
	for(j = (int)b.v.size() - 1;j>=0;j--){
		while(i < (int)a.v.size() && (b.v[j].first | a.v[i].first) < x) i++;
		if(i == (int)a.v.size()) break;
		tmp.val += (long long)b.v[j].second * (a.sum.back() - (i == 0 ? 0 : a.sum[i-1]));
	}
	cur = 0;
	if(c){
		for(int i=0;i<a2.v.size();i++){
			cur |= a2.v[i].first;
			tmp.v.push_back(a2.v[i]);
		}
		for(int i=0;i<b.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (b.v[i].first | cur))
				tmp.v.back().second += b.v[i].second;
			else
				tmp.v.push_back(make_pair((b.v[i].first | cur),b.v[i].second));
		}
	}
	else{
		for(int i=0;i<b2.v.size();i++){
			cur |= b2.v[i].first;
			tmp.v.push_back(b2.v[i]);
		}
		for(int i=0;i<a.v.size();i++){
			if((int)tmp.v.size() > 0 && tmp.v.back().first == (a.v[i].first | cur))
				tmp.v.back().second += a.v[i].second;
			else
				tmp.v.push_back(make_pair((a.v[i].first | cur),a.v[i].second));
		}
	}
	if((int)tmp.v.size() > 0) tmp.sum.push_back(tmp.v[0].second);
	for(int i = 1;i<(int)tmp.v.size();i++)
		tmp.sum.push_back(tmp.sum.back() + tmp.v[i].second);
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][0].v.push_back(make_pair(arr[s],1));
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v.push_back(make_pair(arr[s],1));
		seg[idx][1].val = (arr[s] >= x);
		seg[idx][0].sum.push_back(1);
		seg[idx][1].sum.push_back(1);
		return;
	}
	update(s,(s+e)/2,idx*2);
	update((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void get(int s,int e,int idx){
	if(s > r || e < l){
		tmpp[idx][0].cl();
		tmpp[idx][1].cl();
		return;
	}
	if(s >= l && e <= r){
		doit(tmpp[idx][0],seg[idx][0]);
		doit(tmpp[idx][1],seg[idx][1]);
		return;
	}
	get(s,(s+e)/2,idx*2);
	get((s+e)/2+1,e,idx*2+1);
	tmpp[idx][0] = make(tmpp[idx*2][0],tmpp[idx*2+1][1],tmpp[idx*2][1],tmpp[idx*2+1][0],0);
	tmpp[idx][1] = make(tmpp[idx*2][0],tmpp[idx*2+1][1],tmpp[idx*2][1],tmpp[idx*2+1][0],1);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx2,&val);
			idx2--;
			update(0,n-1,1);
		}
		else{
			scanf("%d%d",&l,&r);
			l--,r--;
			get(0,n-1,1);
			printf("%lld\n",tmpp[1][0].val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx , k ;

struct S{
	map < int , long long > v;
	long long val;
	S(){
		v.clear();
		val = 0;
	}
};

S seg[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	for (map < int , long long > :: iterator it = a.v.begin() ;it != a.v.end();it++){
		for(map < int , long long > :: iterator it2=  b.v.begin() ;it2 != b.v.end();it2++){
			if(((it -> first) | (it2->first)) >= x)
				tmp.val += it->second * it2->second;
		}
	}
	cur = 0;
	if(c){
		for(map < int , long long > :: iterator it = a2.v.begin();it != a2.v.end();it++){
			cur |= it->first;
			tmp.v[it->first] += it->second;
		}
		for(map < int , long long > :: iterator it = b.v.begin();it != b.v.end();it++){
			tmp.v[((it->first) | cur)] += it->second;
		}
	}
	else{
		for(map < int , long long > :: iterator it = b2.v.begin();it != b2.v.end();it++){
			cur |= it->first;
			tmp.v[it->first] += it->second;
		}
		for(map < int , long long > :: iterator it = a.v.begin();it != a.v.end();it++){
			tmp.v[((it->first) | cur)] += it->second;
		}
	}
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v[arr[s]] = 1;
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v[arr[s]] = 1;
		seg[idx][1].val = (arr[s] >= x);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx,int idx2,int val){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][1].val = 0;
		seg[idx][0].val = 0;
		seg[idx][0].v[arr[s]] = 1;
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v[arr[s]] = 1;
		seg[idx][1].val = (arr[s] >= x);
		return;
	}
	update(s,(s+e)/2,idx*2,idx2,val);
	update((s+e)/2+1,e,idx*2+1,idx2,val);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

S get(int s,int e,int idx,int l,int r,bool b){
	if(s > r || e < l)
		return S();
	if(s >= l && e <= r)
		return seg[idx][b];
	S tmp1 = get(s,(s+e)/2,idx*2,l,r,0);
	S tmp2 = get((s+e)/2+1,e,idx*2+1,l,r,1);
	S tmp3 = get(s,(s+e)/2,idx*2,l,r,1);
	S tmp4 = get((s+e)/2+1,e,idx*2+1,l,r,0);
	return make(tmp1,tmp2,tmp3,tmp4,b);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx,&val);
			update(0,n-1,1,idx-1,val);
		}
		else{
			scanf("%d%d",&l,&r);
			printf("%lld\n",get(0,n-1,1,l-1,r-1,0).val);
		}
	}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define oo 2000000000
const int N = 100010;
int n, m , x, cur = 0 , arr[N] , l , r , val , idx , k ;

struct S{
	map < int , long long > v;
	long long val;
	S(){
		v.clear();
		val = 0;
	}
};

S seg[4 * N][2];

S make(S &a,S &b,S &a2,S &b2,bool c){
	S tmp;
	tmp.val += a.val + b.val;
	for (map < int , long long > :: iterator it = a.v.begin() ;it != a.v.end();it++){
		for(map < int , long long > :: iterator it2=  b.v.begin() ;it2 != b.v.end();it2++){
			if(((it -> first) | (it2->first)) >= x)
				tmp.val += it->second * it2->second;
		}
	}
	cur = 0;
	if(c){
		for(map < int , long long > :: iterator it = a2.v.begin();it != a2.v.end();it++){
			cur |= it->first;
			tmp.v[it->first] += it->second;
		}
		for(map < int , long long > :: iterator it = b.v.begin();it != b.v.end();it++){
			tmp.v[((it->first) | cur)] += it->second;
		}
	}
	else{
		for(map < int , long long > :: iterator it = b2.v.begin();it != b2.v.end();it++){
			cur |= it->first;
			tmp.v[it->first] += it->second;
		}
		for(map < int , long long > :: iterator it = a.v.begin();it != a.v.end();it++){
			tmp.v[((it->first) | cur)] += it->second;
		}
	}
	return tmp;

}

void build(int s,int e,int idx){
	if(s == e){
		seg[idx][0].v[arr[s]] = 1;
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v[arr[s]] = 1;
		seg[idx][1].val = (arr[s] >= x);
		return ;
	}
	build(s,(s+e)/2,idx*2);
	build((s+e)/2+1,e,idx*2+1);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

void update(int s,int e,int idx,int idx2,int val){
	if(s > idx2 || e < idx2)
		return;
	if(s == e){
		arr[s] = val;
		seg[idx][0].v.clear();
		seg[idx][1].v.clear();
		seg[idx][1].val = 0;
		seg[idx][0].val = 0;
		seg[idx][0].v[arr[s]] = 1;
		seg[idx][0].val = (arr[s] >= x);
		seg[idx][1].v[arr[s]] = 1;
		seg[idx][1].val = (arr[s] >= x);
		return;
	}
	update(s,(s+e)/2,idx*2,idx2,val);
	update((s+e)/2+1,e,idx*2+1,idx2,val);
	seg[idx][0] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],0);
	seg[idx][1] = make(seg[idx*2][0],seg[idx*2+1][1],seg[idx*2][1],seg[idx*2+1][0],1);
}

S get(int s,int e,int idx,int l,int r,bool b){
	if(s > r || e < l)
		return S();
	if(s >= l && e <= r)
		return seg[idx][b];
	S tmp1 = get(s,(s+e)/2,idx*2,l,r,0);
	S tmp2 = get((s+e)/2+1,e,idx*2+1,l,r,1);
	S tmp3 = get(s,(s+e)/2,idx*2,l,r,1);
	S tmp4 = get((s+e)/2+1,e,idx*2+1,l,r,0);
	return make(tmp1,tmp2,tmp3,tmp4,b);
}

int main(){
	scanf("%d%d%d",&n,&m,&x);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
	}
	build(0,n-1,1);
	while(m--){
		scanf("%d",&k);
		if(k == 1){
			scanf("%d%d",&idx,&val);
			update(0,n-1,1,idx-1,val);
		}
		else{
			scanf("%d%d",&l,&r);
			if(n > N / 2) continue;
			printf("%lld\n",get(0,n-1,1,l-1,r-1,0).val);
		}
	}
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const LL N=100005;
LL n,m,X;
struct qt
{
	LL tot;
	LL c[21],c1[21];
	LL l,r;
	void print()
	{
		printf("l:%lld r:%lld tot:%lld\n",l,r,tot);
		for (LL u=0;u<=5;u++) printf("%lld ",c[u]);
		printf("\n");
		for (LL u=0;u<=5;u++) printf("%lld ",c1[u]);
		printf("\n");
	}
};
struct qq
{
	LL l,r;
	LL s1,s2;
	qt c;
}tr[N*2];LL num;
LL a[N];
void calc (LL now,LL x,LL xx)
{
	for (LL u=0;u<=20;u++)
	{
		LL t=(1<<u);
		if ((t&xx)!=0)	tr[now].c.c[u]=tr[now].c.c1[u]=x;
		else tr[now].c.c[u]=tr[now].c.c1[u]=-1;
	}
	tr[now].c.tot=(xx>=X);
}
struct qr
{
	LL x,id;
};
LL f[100],g[100];
bool cmp (qr x,qr y)	{return x.id>y.id;}
qr A[50],B[50];
qt Merge (qt x,qt y)
{
	if (x.tot==-1) return y;
//	printf("x:");x.print();
//	printf("y:");y.print();
	qt ans;

	for (LL u=0;u<=20;u++)
	{
		if (x.c[u]==-1) ans.c[u]=y.c[u];
		else ans.c[u]=x.c[u];
		ans.c1[u]=max(x.c1[u],y.c1[u]);
	}
	ans.l=x.l;ans.r=y.r;
	ans.tot=x.tot+y.tot;
	for (LL u=0;u<=20;u++)	{A[u].x=(1<<u);A[u].id=x.c1[u];}
	for (LL u=0;u<=20;u++)	{B[u].x=(1<<u);B[u].id=y.c[u];}
	B[21].id=y.l;	B[21].x=0;
	A[21].id=x.r;	A[21].x=0;
	sort(A,A+22,cmp);
	sort(B,B+22,cmp);
	//A按右往左排
	for (LL u=0;u<=21;u++)	{f[u]=f[u-1];if (A[u].id==-1) break;f[u]|=(A[u].x);}
	for (LL u=21;u>=0;u--)	{g[u]=g[u+1];if (B[u].id==-1) continue;g[u]|=(B[u].x);}
	//for (LL u=0;u<=21;u++) printf("OZY:%lld %lld\n",B[u].id,B[u].x);
	LL now=0;//现在在哪里
	LL last=y.r+1;
	for (LL u=0;u<=21;u++)
	{
		if (B[u].id==-1) break;
		if (u!=0&&B[u].id==B[u-1].id) continue;
		while (now<=20)
		{
			if ((f[now]|g[u])>=X) break;
			now++;
			if (A[now].id==-1) break;
		}
		if (now>20||A[now].id==-1) break;
		if (u==0) ans.tot=ans.tot+(last-B[u].id)*(A[now].id-x.l+1);
		else ans.tot=ans.tot+(last-B[u].id)*(A[now].id-x.l+1);
		//printf("%lld %lld %lld %lld %lld\n",last,B[u].id,A[now].id,f[now],x.l);
		last=B[u].id;
	}
	//printf("ans:");ans.print();
//	system("pause");
	return ans;
}
void bt (LL l,LL r)
{
	LL o=++num;
	tr[o].l=l;tr[o].r=r;
	tr[o].c.l=l;tr[o].c.r=r;
	if (l==r)	{calc(o,l,a[l]);return ;}
	LL mid=(l+r)>>1;
	tr[o].s1=num+1;bt(l,mid);
	tr[o].s2=num+1;bt(mid+1,r);
	tr[o].c=Merge(tr[tr[o].s1].c,tr[tr[o].s2].c);
}
void change (LL now,LL x,LL xx)
{
	if (tr[now].l==tr[now].r)	{calc(now,x,xx);return ;}
	LL mid=(tr[now].l+tr[now].r)>>1;
	LL s1=tr[now].s1,s2=tr[now].s2;
	if (x<=mid) change(s1,x,xx);
	else change(s2,x,xx);
	tr[now].c=Merge(tr[s1].c,tr[s2].c);
}
qt ans;
void find (LL now,LL l,LL r)
{
	if (tr[now].l==l&&tr[now].r==r)
	{
		ans=Merge(ans,tr[now].c);
		return ;
	}
	LL mid=(tr[now].l+tr[now].r)>>1;
	LL s1=tr[now].s1,s2=tr[now].s2;
	if (r<=mid) find(s1,l,r);
	else if (l>mid) find(s2,l,r);
	else find(s1,l,mid),find(s2,mid+1,r);
}
int main()
{
	scanf("%lld%lld%lld",&n,&m,&X);
	for (LL u=1;u<=n;u++)	scanf("%lld",&a[u]);
	bt(1,n);
	for (LL u=1;u<=m;u++)
	{
		LL op;
		scanf("%lld",&op);
		if (op==1)
		{
			LL x,y;
			scanf("%lld%lld",&x,&y);
			change(1,x,y);
		}
		else
		{
			LL l,r;
			scanf("%lld%lld",&l,&r);
			ans.tot=-1;
			find(1,l,r);
			printf("%lld\n",ans.tot);
		}
	}
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=100005;
int n,m,X;
struct qt
{
	LL tot;
	int c[21],c1[21];
	int l,r;
	void print()
	{
		printf("l:%d r:%d tot:%d\n",l,r,tot);
		for (int u=0;u<=5;u++) printf("%d ",c[u]);
		printf("\n");
		for (int u=0;u<=5;u++) printf("%d ",c1[u]);
		printf("\n");
	}
};
struct qq
{
	int l,r;
	int s1,s2;
	qt c;
}tr[N*2];int num;
int a[N];
void calc (int now,int x,int xx)
{
	for (int u=0;u<=20;u++)
	{
		int t=(1<<u);
		if ((t&xx)!=0)	tr[now].c.c[u]=tr[now].c.c1[u]=x;
		else tr[now].c.c[u]=tr[now].c.c1[u]=-1;
	}
	tr[now].c.tot=(xx>=X);
}
struct qr
{
	int x,id;
};
int f[100],g[100];
bool cmp (qr x,qr y)	{return x.id>y.id;}
qr A[50],B[50];
qt Merge (qt x,qt y)
{
	if (x.tot==-1) return y;
//	printf("x:");x.print();
//	printf("y:");y.print();
	qt ans;

	for (int u=0;u<=20;u++)
	{
		if (x.c[u]==-1) ans.c[u]=y.c[u];
		else ans.c[u]=x.c[u];
		ans.c1[u]=max(x.c1[u],y.c1[u]);
	}
	ans.l=x.l;ans.r=y.r;
	ans.tot=x.tot+y.tot;
	for (int u=0;u<=20;u++)	{A[u].x=(1<<u);A[u].id=x.c1[u];}
	for (int u=0;u<=20;u++)	{B[u].x=(1<<u);B[u].id=y.c[u];}
	B[21].id=y.l;	B[21].x=0;
	A[21].id=x.r;	A[21].x=0;
	sort(A,A+22,cmp);
	sort(B,B+22,cmp);
	//A按右往左排
	for (int u=0;u<=21;u++)	{f[u]=f[u-1];if (A[u].id==-1) break;f[u]|=(A[u].x);}
	for (int u=21;u>=0;u--)	{g[u]=g[u+1];if (B[u].id==-1) continue;g[u]|=(B[u].x);}
	//for (int u=0;u<=21;u++) printf("OZY:%d %d\n",B[u].id,B[u].x);
	int now=0;//现在在哪里
	int last=y.r+1;
	for (int u=0;u<=21;u++)
	{
		if (B[u].id==-1) break;
		if (u!=0&&B[u].id==B[u-1].id) continue;
		while (now<=21)
		{
			if ((f[now]|g[u])>=X) break;
			now++;
			if (A[now].id==-1) break;
		}
		if (now>21||A[now].id==-1) break;
		if (u==0) ans.tot=ans.tot+(LL)(last-B[u].id)*(A[now].id-x.l+1);
		else ans.tot=ans.tot+(LL)(last-B[u].id)*(A[now].id-x.l+1);
		//printf("%d %d %d %d %d\n",last,B[u].id,A[now].id,f[now],x.l);
		last=B[u].id;
	}
	//printf("ans:");ans.print();
//	system("pause");
	return ans;
}
void bt (int l,int r)
{
	int o=++num;
	tr[o].l=l;tr[o].r=r;
	tr[o].c.l=l;tr[o].c.r=r;
	if (l==r)	{calc(o,l,a[l]);return ;}
	int mid=(l+r)>>1;
	tr[o].s1=num+1;bt(l,mid);
	tr[o].s2=num+1;bt(mid+1,r);
	tr[o].c=Merge(tr[tr[o].s1].c,tr[tr[o].s2].c);
}
void change (int now,int x,int xx)
{
	if (tr[now].l==tr[now].r)	{calc(now,x,xx);return ;}
	int mid=(tr[now].l+tr[now].r)>>1;
	int s1=tr[now].s1,s2=tr[now].s2;
	if (x<=mid) change(s1,x,xx);
	else change(s2,x,xx);
	tr[now].c=Merge(tr[s1].c,tr[s2].c);
}
qt ans;
void find (int now,int l,int r)
{
	if (tr[now].l==l&&tr[now].r==r)
	{
		ans=Merge(ans,tr[now].c);
		return ;
	}
	int mid=(tr[now].l+tr[now].r)>>1;
	int s1=tr[now].s1,s2=tr[now].s2;
	if (r<=mid) find(s1,l,r);
	else if (l>mid) find(s2,l,r);
	else find(s1,l,mid),find(s2,mid+1,r);
}
int read ()
{
	char ch=getchar();int x=0;
	while (ch<'0'||ch>'9') ch=getchar();
	while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
	return x;
}
int main()
{
	n=read();m=read();X=read();
	for (int u=1;u<=n;u++)	a[u]=read();
	bt(1,n);
	for (int u=1;u<=m;u++)
	{
		int op=read();
		if (op==1)
		{
			int x,y;
			x=read();y=read();
			change(1,x,y);
		}
		else
		{
			int l,r;
			l=read();r=read();
			ans.tot=-1;
			find(1,l,r);
			printf("%lld\n",ans.tot);
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (ll) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (ll)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <ll, ll> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const ll inf = numeric_limits <ll>::max() >> 1;
const ll N = 1e5 + 1;
const ll L = 20;
ll n, q, val;
ll mask[N];

void add(ll &curmask, ll i, ll x, ll bit[L]) {
    bit[i] += x;
    if(bit[i] <= 0) {
        curmask &= ~(1 << i);
    } else {
        curmask |= 1 << i;
    }
}

struct Data {
    ll l, r;
    ll sum = 0;
    ll cnt = 0;
    ll pre[L] = {0};
    ll suf[L] = {0};

    Data operator + (Data &p) {
        Data res;
        vec <pii> suff;
        vec <pii> pref;
        for(ll i = 0; i < L; ++i) {
            res.pre[i] = pre[i]? pre[i]: p.pre[i];
            res.suf[i] = p.suf[i]? p.suf[i]: suf[i];
            if(suf[i]) {
                suff.pb({suf[i], i});
            }
            if(p.pre[i]) {
                pref.pb({p.pre[i], i});
            }
        }
        sort(all(suff), greater <pii> {});
        sort(all(pref), less <pii> {});
        res.l = l;
        res.r = p.r;
        res.sum = sum + p.sum;
        res.cnt = cnt + p.cnt;
        ll lst = l - 1;
        ll j = 0;
        ll i = len(suff) - 1;
        ll curmask = 0;
        ll bit[L] = {0};
        for(ll iter = 0; iter < len(suff); ++iter) {
            curmask |= 1 << suff[iter].yy;
            bit[suff[iter].yy]++;
        }
        for(; i >= 0; --i) {
            for(; j < len(pref) && curmask < val; ++j) {
                add(curmask, pref[j].yy, 1, bit);
            }
            if(curmask >= val) {
                if(j) {
                    res.cnt += (suff[i].xx - lst);
                    res.sum += (suff[i].xx - lst) * pref[j - 1].xx;
                }
            }
            add(curmask, suff[i].yy, -1, bit);
            lst = suff[i].xx;
        }
        for(; j < len(pref) && curmask < val; ++j) {
            add(curmask, pref[j].yy, 1, bit);
        }
        if(curmask >= val) {
            if(j) {
                res.cnt += (r - lst);
                res.sum += (r - lst) * pref[j - 1].xx;
            }
        }
        return res;
    }
};

struct Node {
    ll l, r;
    Data data;
} node[N << 2];

void input() {
    cin >> n >> q >> val;
    for(ll i = 1; i <= n; ++i) {
        cin >> mask[i];
    }
}

void merge(ll id, ll l, ll r) {
    node[id].data = node[l].data + node[r].data;
}

void build(ll id, ll l, ll r) {
    node[id].l = l;
    node[id].r = r;
    node[id].data.l = l;
    node[id].data.r = r;
    if(l == r) {
        node[id].data.sum = 0;
        node[id].data.cnt = 0;
        if(mask[l] >= val) {
            node[id].data.sum = l;
            node[id].data.cnt++;
        }
        for(ll i = 0; i < L; ++i) {
            if((mask[l] >> i) & 1) {
                node[id].data.pre[i] = l;
                node[id].data.suf[i] = l;
            } else {
                node[id].data.pre[i] = 0;
                node[id].data.suf[i] = 0;
            }
        }
        return;
    }
    ll q = l + r >> 1;
    build(l(id), l, q);
    build(r(id), q + 1, r);
    merge(id, l(id), r(id));
}

void update(ll id, ll i) {
    if(node[id].l == node[id].r) {
        node[id].data.sum = 0;
        node[id].data.cnt = 0;
        if(mask[i] >= val) {
            node[id].data.sum = i;
            node[id].data.cnt++;
        }
        for(ll j = 0; j < L; ++j) {
            if((mask[i] >> j) & 1) {
                node[id].data.pre[j] = i;
                node[id].data.suf[j] = i;
            } else {
                node[id].data.pre[j] = 0;
                node[id].data.suf[j] = 0;
            }
        }
        return;
    }
    ll q = node[id].l + node[id].r >> 1;
    if(i <= q) {
        update(l(id), i);
    } else {
        update(r(id), i);
    }
    merge(id, l(id), r(id));
}

Data query(ll id, ll l, ll r) {
    if(node[id].l == l && node[id].r == r) {
        return node[id].data;
    }
    Data res;
    res.l = l;
    res.r = l - 1;
    ll q = node[id].l + node[id].r >> 1;
    if(l <= q) {
        Data qres = query(l(id), l, min(q, r));
        res = res + qres;
    }
    if(r > q) {
        Data qres = query(r(id), max(q + 1, l), r);
        res = res + qres;
    }
    return res;
}

void solve() {
    build(0, 1, n);
    for(ll i = 0; i < q; ++i) {
        ll t; cin >> t;
        if(t == 1) {
            ll k; cin >> k;
            ll x; cin >> x;
            mask[k] = x;
            update(0, k);
        } else {
            ll l; cin >> l;
            ll r; cin >> r;
            Data res = query(0, l, r);
            cout << res.cnt * (r + 1) - res.sum << "\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (ll) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (ll)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <ll, ll> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const ll inf = numeric_limits <ll>::max() >> 1;
const ll N = 1e5 + 1;
const ll L = 20;
ll n, q, val;
ll mask[N];

void compress(vec <pii> &arg) {
    bitset <L> was = 0;
    vec <pii> result;
    for(pii p: arg) {
        if(!was[p.yy]) {
            result.pb(p);
        }
        was[p.yy] = 1;
    }
    arg = result;
}

void add(ll &curmask, ll i, ll x, ll bit[L]) {
    bit[i] += x;
    if(bit[i] <= 0) {
        curmask &= ~(1 << i);
    } else {
        curmask |= 1 << i;
    }
}

struct Data {
    ll l, r;
    ll sum = 0;
    ll cnt = 0;
    vec <pii> pre;
    vec <pii> suf;

    Data operator + (Data &p) {
        Data res;
        merge(all(pre), all(p.pre), back_inserter(res.pre), less <pii> {});
        merge(all(suf), all(p.suf), back_inserter(res.suf), greater <pii> {});
        compress(res.pre);
        compress(res.suf);
        res.l = l;
        res.r = p.r;
        res.sum = sum + p.sum;
        res.cnt = cnt + p.cnt;
        ll lst = l - 1;
        ll j = 0;
        ll i = len(suf) - 1;
        ll curmask = 0;
        ll bit[L] = {0};
        for(ll iter = 0; iter < len(suf); ++iter) {
            curmask |= 1 << suf[iter].yy;
            bit[suf[iter].yy]++;
        }
        for(; i >= 0; --i) {
            for(; j < len(p.pre) && curmask < val; ++j) {
                add(curmask, p.pre[j].yy, 1, bit);
            }
            if(curmask >= val) {
                if(j) {
                    res.cnt += (suf[i].xx - lst);
                    res.sum += (suf[i].xx - lst) * p.pre[j - 1].xx;
                }
            }
            add(curmask, suf[i].yy, -1, bit);
            lst = suf[i].xx;
        }
        for(; j < len(p.pre) && curmask < val; ++j) {
            add(curmask, p.pre[j].yy, 1, bit);
        }
        if(curmask >= val) {
            if(j) {
                res.cnt += (r - lst);
                res.sum += (r - lst) * p.pre[j - 1].xx;
            }
        }
        return res;
    }
};

struct Node {
    ll l, r;
    Data data;
} node[N << 2];

void input() {
    cin >> n >> q >> val;
    for(ll i = 1; i <= n; ++i) {
        cin >> mask[i];
    }
}

void merge(ll id, ll l, ll r) {
    node[id].data = node[l].data + node[r].data;
}

void build(ll id, ll l, ll r) {
    node[id].l = l;
    node[id].r = r;
    node[id].data.l = l;
    node[id].data.r = r;
    if(l == r) {
        node[id].data.sum = 0;
        node[id].data.cnt = 0;
        if(mask[l] >= val) {
            node[id].data.sum = l;
            node[id].data.cnt++;
        }
        for(ll i = 0; i < L; ++i) {
            if((mask[l] >> i) & 1) {
                node[id].data.pre.pb({l, i});
                node[id].data.suf.pb({l, i});
            }
        }
        return;
    }
    ll q = l + r >> 1;
    build(l(id), l, q);
    build(r(id), q + 1, r);
    merge(id, l(id), r(id));
}

void update(ll id, ll i) {
    if(node[id].l == node[id].r) {
        node[id].data.sum = 0;
        node[id].data.cnt = 0;
        if(mask[i] >= val) {
            node[id].data.sum = i;
            node[id].data.cnt++;
        }
        node[id].data.pre.clear();
        node[id].data.suf.clear();
        for(ll j = 0; j < L; ++j) {
            if((mask[i] >> j) & 1) {
                node[id].data.pre.pb({i, j});
                node[id].data.suf.pb({i, j});
            }
        }
        return;
    }
    ll q = node[id].l + node[id].r >> 1;
    if(i <= q) {
        update(l(id), i);
    } else {
        update(r(id), i);
    }
    merge(id, l(id), r(id));
}

Data query(ll id, ll l, ll r) {
    if(node[id].l == l && node[id].r == r) {
        return node[id].data;
    }
    Data res;
    res.l = l;
    res.r = l - 1;
    ll q = node[id].l + node[id].r >> 1;
    if(l <= q) {
        Data qres = query(l(id), l, min(q, r));
        res = res + qres;
    }
    if(r > q) {
        Data qres = query(r(id), max(q + 1, l), r);
        res = res + qres;
    }
    return res;
}

void solve() {
    build(0, 1, n);
    for(ll i = 0; i < q; ++i) {
        ll t; cin >> t;
        if(t == 1) {
            ll k; cin >> k;
            ll x; cin >> x;
            mask[k] = x;
            update(0, k);
        } else {
            ll l; cin >> l;
            ll r; cin >> r;
            Data res = query(0, l, r);
            cout << res.cnt * (r + 1) - res.sum << "\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (ll) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (ll)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <ll, ll> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const ll inf = numeric_limits <ll>::max() >> 1;
const ll N = 1e5 + 1;
const ll L = 20;
ll n, q, val;
ll mask[N];

void compress(vec <pii> &arg) {
    bitset <L> was = 0;
    vec <pii> result;
    for(pii p: arg) {
        if(!was[p.yy]) {
            result.pb(p);
        }
        was[p.yy] = 1;
    }
    arg = result;
}

void add(ll &curmask, ll i, ll x, ll bit[L]) {
    bit[i] += x;
    if(bit[i] <= 0) {
        curmask &= ~(1 << i);
    } else {
        curmask |= 1 << i;
    }
}

struct Data {
    ll l, r;
    ll sum = 0;
    ll cnt = 0;
    vec <pii> pre;
    vec <pii> suf;

    Data operator + (const Data &p) const {
        Data res;
        int maskpre = 0;
        int masksuf = 0;
        for(const pii &p: pre) {
            maskpre |= 1 << p.yy;
            res.pre.pb(p);
        }
        for(const pii &p: p.suf) {
            masksuf |= 1 << p.yy;
            res.suf.pb(p);
        }
        for(const pii &p: p.pre) {
            if(!((maskpre >> p.yy) & 1)) {
                res.pre.pb(p);
            }
        }
        for(const pii &p: suf) {
            if(!((masksuf >> p.yy) & 1)) {
                res.suf.pb(p);
            }
        }
        res.l = l;
        res.r = p.r;
        res.sum = sum + p.sum;
        res.cnt = cnt + p.cnt;
        ll lst = l - 1;
        ll j = 0;
        ll i = len(suf) - 1;
        ll curmask = 0;
        ll bit[L] = {0};
        for(ll iter = 0; iter < len(suf); ++iter) {
            curmask |= 1 << suf[iter].yy;
            bit[suf[iter].yy]++;
        }
        for(; i >= 0; --i) {
            for(; j < len(p.pre) && curmask < val; ++j) {
                add(curmask, p.pre[j].yy, 1, bit);
            }
            if(curmask >= val) {
                if(j) {
                    res.cnt += (suf[i].xx - lst);
                    res.sum += (suf[i].xx - lst) * p.pre[j - 1].xx;
                }
            }
            add(curmask, suf[i].yy, -1, bit);
            lst = suf[i].xx;
        }
        for(; j < len(p.pre) && curmask < val; ++j) {
            add(curmask, p.pre[j].yy, 1, bit);
        }
        if(curmask >= val) {
            if(j) {
                res.cnt += (r - lst);
                res.sum += (r - lst) * p.pre[j - 1].xx;
            }
        }
        return res;
    }
};

struct Node {
    ll l, r;
    Data data;
} node[N << 2];

void input() {
    cin >> n >> q >> val;
    for(ll i = 1; i <= n; ++i) {
        cin >> mask[i];
    }
}

void merge(ll id, ll l, ll r) {
    node[id].data = node[l].data + node[r].data;
}

void build(ll id, ll l, ll r) {
    node[id].l = l;
    node[id].r = r;
    node[id].data.l = l;
    node[id].data.r = r;
    if(l == r) {
        node[id].data.sum = 0;
        node[id].data.cnt = 0;
        if(mask[l] >= val) {
            node[id].data.sum = l;
            node[id].data.cnt++;
        }
        for(ll i = 0; i < L; ++i) {
            if((mask[l] >> i) & 1) {
                node[id].data.pre.pb({l, i});
                node[id].data.suf.pb({l, i});
            }
        }
        return;
    }
    ll q = l + r >> 1;
    build(l(id), l, q);
    build(r(id), q + 1, r);
    merge(id, l(id), r(id));
}

void update(ll id, ll i) {
    if(node[id].l == node[id].r) {
        node[id].data.sum = 0;
        node[id].data.cnt = 0;
        if(mask[i] >= val) {
            node[id].data.sum = i;
            node[id].data.cnt++;
        }
        node[id].data.pre.clear();
        node[id].data.suf.clear();
        for(ll j = 0; j < L; ++j) {
            if((mask[i] >> j) & 1) {
                node[id].data.pre.pb({i, j});
                node[id].data.suf.pb({i, j});
            }
        }
        return;
    }
    ll q = node[id].l + node[id].r >> 1;
    if(i <= q) {
        update(l(id), i);
    } else {
        update(r(id), i);
    }
    merge(id, l(id), r(id));
}

Data query(ll id, ll l, ll r) {
    if(node[id].l == l && node[id].r == r) {
        return node[id].data;
    }
    Data res;
    res.l = l;
    res.r = l - 1;
    ll q = node[id].l + node[id].r >> 1;
    if(l <= q) {
        Data qres = query(l(id), l, min(q, r));
        res = res + qres;
    }
    if(r > q) {
        Data qres = query(r(id), max(q + 1, l), r);
        res = res + qres;
    }
    return res;
}

void solve() {
    build(0, 1, n);
    for(ll i = 0; i < q; ++i) {
        ll t; cin >> t;
        if(t == 1) {
            ll k; cin >> k;
            ll x; cin >> x;
            mask[k] = x;
            update(0, k);
        } else {
            ll l; cin >> l;
            ll r; cin >> r;
            Data res = query(0, l, r);
            cout << res.cnt * (r + 1) - res.sum << "\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/trie_policy.hpp>
#include <ext/rope>

#pragma GCC optimize("Ofast")
#pragma GCC optimization("unroll-loops, no-stack-protector")
#pragma GCC target("avx,avx2,fma")

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define gcd __gcd
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define rep(i, n) for (int i=0; i<(n); i++)
#define rep1(i, n) for (int i=1; i<=(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define endl "\n"

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned uint;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
template<typename _def> using ordered_set=tree<_def, null_type, less<_def>, rb_tree_tag, tree_order_statistics_node_update>;
typedef trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update> pref_trie;

//Note
//Complexity: I think O(n log n log MAX)

//there is also a divide and conquer solution
//although I don't really understand how to optimize the thing
//from O(n log^3) to n log^2
//and I am more comfortable with segtrees than totally exotic structs anyway

//enough about that

//Extra note:
//so if you squint really hard this does exactly the same thing as the other solution
//so ...
//well whatever

constexpr int N=1e5+2;
int a[N];
int n, x;

struct node {
    ll ans;
    int all;
    int l, r;
    vector<pii> pf, sf; //first is or sum, second is position
    node() {ans=all=l=r=0; pf.clear(), sf.clear();}
    node(int p, int v) {
        l=r=p;
        pf.eb(v, p), sf.eb(v, p);
        all=v; ans=v>=x;
    }
    friend node operator + (const node& a, const node& b) {
        node res;
        res.l=a.l; res.r=b.r;
        res.all=a.all|b.all;
        res.ans=a.ans+b.ans;
        res.pf=a.pf; res.sf=b.sf;
        for(const pii& it: b.pf) {
            const int v=it.fi, p=it.se;
            if((a.all|v)!=res.pf.back().fi) res.pf.eb(a.all|v, p);
        }
        for(const pii& it: a.sf) {
            const int v=it.fi, p=it.se;
            if((b.all|v)!=res.sf.back().fi) res.sf.eb(b.all|v, p);
        }
        int j=0;
        for(int i=b.pf.size()-1; i>=0; i--) {
            while(j<a.sf.size()&&(b.pf[i].fi|a.sf[j].fi)<x) j++;
            if (j<a.sf.size()) {
                const int u=(i<b.pf.size()-1?b.pf[i+1].se:b.r+1)-b.pf[i].se;
                const int v=a.sf[j].se-a.l+1;
                res.ans+=1LL*u*v;
            }
            else break;
        }
        return res;
    }
} t[4*N+4];

void build(int a[], int v=1, int l=1, int r=n) {
    if(l==r) t[v]=node(l, a[l]);
    else {
        int m=(l+r)/2;
        build(a, v*2, l, m);
        build(a, v*2+1, m+1, r);
        t[v]=t[v*2]+t[v*2+1];
    }
}

void upd(int pos, int val, int v=1, int tl=1, int tr=n) {
    if(tl==tr) t[v]=node(pos, val);
    else {
        int tm=(tl+tr)/2;
        if(pos<=tm) upd(pos, val, v*2, tl, tm);
        else upd(pos, val, v*2+1, tm+1, tr);
        t[v]=t[v*2]+t[v*2+1];
    }
}

node get(int l, int r, int v=1, int tl=1, int tr=n) {
    if(l==tl&&r==tr) return t[v];
    else {
        int tm=(tl+tr)/2;
        if(r<=tm) return get(l, r, v*2, tl, tm);
        else if(l>tm) return get(l, r, v*2+1, tm+1, tr);
        else return get(l, tm, v*2, tl, tm)+get(tm+1, r, v*2+1, tm+1, tr);
    }
}

int32_t main() {
    fastio;
    int m; cin>>n>>m>>x;
    rep1(i, n) cin>>a[i];
    build(a);
    while(m--) {
        int t; cin>>t;
        if(t==1) {
            int pos, val;
            cin>>pos>>val;
            upd(pos, val);
        }
        else {
            int l, r;
            cin>>l>>r;
            cout<<get(l, r).ans<<endl;
        }
    }
}


#include<bits/stdc++.h>
#define fi first
#define se second
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;
}