#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define bitcount __builtin_popcountll
#define all(a) (a).begin(), (a).end()
using namespace std;
using namespace __gnu_pbds;
template<typename T> using ordered_set = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
const int N = 1 << 17;
int A[2*N], sum[2*N], mx[2*N];
void calc(int i) {
sum[i] = sum[2*i] + sum[2*i + 1];
mx[i] = max(mx[2*i], mx[2*i + 1]);
}
void build() {
for (int i = 0; i < N; i++)
mx[i + N] = sum[i + N] = A[i];
for (int i = N-1; i > 0; i--)
calc(i);
}
void update(int i, int x) {
i += N;
sum[i] = mx[i] = x;
while (i /= 2)
calc(i);
}
void spray(int ql, int qr, int k, int v = 1, int l = 0, int r = N-1) {
if (mx[v] == 0) return;
if (qr < l || r < ql) return;
if (l == r) {
sum[v] /= k;
mx[v] /= k;
return;
}
int mid = (l + r) / 2;
spray(ql, qr, k, 2 * v, l, mid);
spray(ql, qr, k, 2 * v + 1, mid + 1, r);
calc(v);
}
int query(int ql, int qr, int v = 1, int l = 0, int r = N-1) {
if (ql <= l && r <= qr) return sum[v];
if (qr < l || r < ql) return 0;
int mid = (l+r)/2;
return query(ql, qr, 2*v, l, mid) + query(ql, qr, 2*v + 1, mid+1, r);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int n,q,k; cin >> n >> q >> k;
for (int i = 1; i <= n; i++) {
cin >> A[i];
}
build();
while (q--) {
int t,l,r; cin >> t >> l >> r;
if (t == 1) {
update(l, r);
} else if (t == 2) {
spray(l, r, k);
} else {
cout << query(l, r) << "\n";
}
// for (int l = n; l >= 1; l--) {
// for (int r = l; r <= n; r++) {
// cout << query(l, r) << " ";
// }
// cout << "\n";
// }
}
}