#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N = 2e5 + 10;
using ll = long long;
int n;
struct node
{
int l, r;
ll sum, lz;
}tree[N << 2];
inline int ls(int cur)
{
//求左子节点
return cur << 1;
}
inline int rs(int cur)
{
//求右子节点
return (cur << 1) | 1;
}
void push_up(int cur)
{
//左右子树更新当前区间的值
tree[cur].sum = tree[ls(cur)].sum + tree[rs(cur)].sum;
}
void push_down(int cur)
{
//在查询时,如果子树的值还未进行更新,则对子树进行更新
if (tree[cur].lz) {
tree[ls(cur)].sum += (tree[ls(cur)].r - tree[ls(cur)].l + 1) * tree[cur].lz;
tree[ls(cur)].sum += (tree[rs(cur)].r - tree[rs(cur)].l + 1) * tree[cur].lz;
tree[ls(cur)].lz += tree[cur].lz;
tree[rs(cur)].lz += tree[cur].lz;
tree[cur].lz = 0;
}
}
void build(int cur, int l, int r)
{
tree[cur].l = l;
tree[cur].r = r;
if (l == r) {
//已经到了叶子节点
ll a;
cin >> a;
tree[cur].sum = a;
return;
}
int mid = (tree[cur].l + tree[cur].r) >> 1;
build(ls(cur), l, mid);
build(rs(cur), mid + 1, r);
push_up(cur);
}
void update(int cur, int l, int r, int v)
{
if (tree[cur].l == l and tree[cur].r == r) {
//当前节点正好是要修改的区间
tree[cur].sum += (r - l + 1) * v;
tree[cur].lz += v;
return;
}
//遍历到当前节点时,顺便将子节点的值给更新
push_down(cur);
int mid = (tree[cur].l + tree[cur].r) >> 1;
if (r <= mid) {
//要更新的区间都在当前节点区间的左边
update(ls(cur), l, r, v);
}
else if (l > mid) {
update(rs(cur), l, r, v);
}
else {
update(ls(cur), l, mid, v);
update(rs(cur), mid + 1, r, v);
}
//更新完子节点之后将自己也进行更新
push_up(cur);
}
int query(int cur, int l, int r)
{
if (tree[cur].l == l and tree[cur].r == r)
{
return tree[cur].sum;
}
//对子节点进行查询时,先将子节点值进行更新
push_down(cur);
int mid = (tree[cur].l + tree[cur].r) >> 1;
if (r <= mid) {
return query(ls(cur), l, r);
}
else if (l > mid) {
return query(rs(cur), l, r);
}
else {
return query(ls(cur), l, mid) + query(rs(cur), mid + 1, r);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("D:/VS CODE/C++/in.txt", "r", stdin);
freopen("D:/VS CODE/C++/out.txt", "w", stdout);
#endif
cin >> n;
build(1, 1, n);
return 0;
}