#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 1000005;
const int MAXB = 10005;
int n, m, k;
int a[MAXN];
long long b[MAXN];
int S;
int num_blocks;
int L[MAXB], R[MAXB];
long long lazy[MAXB];
// Các mảng 1D liên tục cho hiệu suất Cache (CPU Cache) cực cao
int sorted_a[MAXN];
int orig_idx[MAXN];
long long sum_b[MAXN];
struct Update {
int p;
long long w;
};
vector<Update> pending[MAXB];
// Áp dụng các cập nhật partial bị trì hoãn (Lazy Rebuild)
void commit(int id) {
if (pending[id].empty()) return;
int l = L[id], r = R[id];
for (const auto& upd : pending[id]) {
int limit = upd.p;
long long w = upd.w;
for (int i = l; i <= limit; ++i) {
b[i] += w;
}
}
pending[id].clear();
// Xây dựng lại mảng tổng tiền tố
long long cur = 0;
for (int i = l; i <= r; ++i) {
cur += b[orig_idx[i]];
sum_b[i] = cur;
}
}
void update_partial(int id, int p, long long w) {
pending[id].push_back({p, w});
}
long long query_full(int id, int d) {
commit(id); // Đồng bộ dữ liệu trước khi truy vấn
int l = L[id], r = R[id];
// Dùng upper_bound với greater<int> để tìm phần tử đầu tiên nhỏ hơn d
int count = upper_bound(sorted_a + l, sorted_a + r + 1, d, greater<int>()) - (sorted_a + l);
if (count == 0) return 0;
return sum_b[l + count - 1] + (long long)count * lazy[id];
}
long long query_partial(int id, int p, int d) {
commit(id); // Đồng bộ dữ liệu
long long ans = 0;
int l = L[id];
for (int i = l; i <= p; ++i) {
if (a[i] >= d) {
ans += b[i] + lazy[id];
}
}
return ans;
}
int main() {
// Tối ưu hóa I/O tốc độ cao
ios_base::sync_with_stdio(false);
cin.tie(NULL);
if (!(cin >> n >> m >> k)) return 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
b[i] = 0;
}
// Thiết lập kích thước block tối ưu
S = max(100, (int)sqrt(n * 10));
num_blocks = (n + S - 1) / S;
for (int i = 0; i < num_blocks; ++i) {
L[i] = i * S;
R[i] = min(n - 1, (i + 1) * S - 1);
lazy[i] = 0;
vector<pair<int, int>> temp;
temp.reserve(R[i] - L[i] + 1);
for (int j = L[i]; j <= R[i]; ++j) {
temp.push_back({a[j], j});
}
// Sắp xếp các phần tử trong block giảm dần theo a_i
sort(temp.begin(), temp.end(), [](const pair<int,int>& x, const pair<int,int>& y){
return x.first > y.first;
});
for (int j = 0; j < (int)temp.size(); ++j) {
sorted_a[L[i] + j] = temp[j].first;
orig_idx[L[i] + j] = temp[j].second;
sum_b[L[i] + j] = 0;
}
}
int q = m + k;
while (q--) {
int type;
cin >> type;
if (type == 1) {
int p;
long long w;
cin >> p >> w;
p--; // Chuyển sang 0-based index
for (int i = 0; i < num_blocks; ++i) {
if (R[i] <= p) {
lazy[i] += w;
} else if (L[i] <= p) {
update_partial(i, p, w);
break;
}
}
} else if (type == 2) {
int p, d;
cin >> p >> d;
p--; // Chuyển sang 0-based index
long long ans = 0;
for (int i = 0; i < num_blocks; ++i) {
if (R[i] <= p) {
ans += query_full(i, d);
} else if (L[i] <= p) {
ans += query_partial(i, p, d);
break;
}
}
cout << ans << "\n";
}
}
return 0;
}