#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <unordered_set>
#include <numeric>
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;
typedef vector<long long> vll;
const int INF = 100000000;
const double pi = 3.14159265358979;
const ll MOD = 1000000007;
ll arr[1000002];
ll lazy[4 * 1000002];
ll tree[4 * 1000002];
ll N, M, K;
ll a, b, c, d;
ll order;
ll init(ll start, ll end, ll node)
{
if (start == end)
return tree[node] = arr[start];
ll mid = (start + end) / 2;
return tree[node] = init(start, mid, node * 2) + init(mid + 1, end, node * 2 + 1);
}
ll query(ll start, ll end, ll node, ll left, ll right)
{
if (left > end || right < start)
return 0;
if (left <= start && end <= right)
return tree[node];
ll mid = (start + end) / 2;
return query(start, mid, node * 2, left, right) + query(mid + 1, end, node * 2 + 1, left, right);
}
ll update(ll start, ll end, ll node, ll index, ll diff)
{
if (index < start || end < index)
return tree[node];
if (start == end)
return tree[node] += diff;;
ll mid = (start + end) / 2;
return tree[node] = update(start, mid, node * 2, index, diff) + update(mid + 1, end, node * 2 + 1, index, diff);
}
void update_lazy(ll start, ll end, ll node) {
if (lazy[node] != 0)
{
tree[node] += (end - start + 1) * lazy[node];
if (start != end)
{
lazy[node * 2] += lazy[node];
lazy[node * 2 + 1] += lazy[node];
}
lazy[node] = 0;
}
}
ll query_range(ll start, ll end, ll node, ll left, ll right)
{
update_lazy(start, end, node);
if (left > end || right < start)
return 0;
if (left <= start && end <= right)
return tree[node];
ll mid = (start + end) / 2;
return query_range(start, mid, node * 2, left, right) + query_range(mid + 1, end, node * 2 + 1, left, right);
}
void update_range(ll start, ll end, ll node, ll left, ll right, ll diff)
{
update_lazy(start, end, node);
if (left > end || right < start)
return;
if (left <= start && end <= right)
{
tree[node] += (end - start + 1) * diff;
if (start != end) {
lazy[node * 2] += diff;
lazy[node * 2 + 1] += diff;
}
return;
}
ll mid = (start + end) / 2;
update_range( start, mid, node * 2, left, right, diff);
update_range( mid + 1, end, node * 2 + 1, left, right, diff);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> N >> M >> K;
rep1(i, N)
{
cin >> a;
arr[i] = a;
}
init(1, N, 1);
rep(i, M + K)
{
cin >> order;
if (order == 1)
{
cin >> a >> b >> c;
update_range(1, N, 1, a, b, c);
}
else if(order == 2)
{
cin >> a >> b;
cout << query_range(1, N, 1, a, b) << "\n";
}
}
return 0;
}