#include<bits/stdc++.h>
using namespace std;
int cnt;//总共有多少个节点
struct node
{
int l,r;//左儿子 右儿子编号
int sum;//区间和
node(){
l=r=sum=0;
}
}z[maxn*logn];
void update(int p)
{
z[p].sum = z[z[p].l].sum + z[z[p].r].sum;
}
int build(int l,int r)//当前的区间为l~r 是这段区间对应的节点编号
{
cnt++;
int p=cnt;
if (l==r)
{
z[p].sum = a[l];
return p;
}
int m=(l+r)>>1;
z[p].l = build(l,m);
z[p].r = build(m+1,r);
update(p);
return p;
}
int query(int l,int r,int rt,int nowl,int nowr)
//当前线段树节点编号为rt 对应的区间为l~r 要询问nowl~nowr这段区间的和
{
if (nowl <= l && r <= nowr) return z[rt].sum;
int m=(l+r)>>1;
if (nowl<=m)
{
if (m<nowr) return query(l,m,z[rt].l,nowl,nowr) + query(m+1,r,z[rt].r,nowl,nowr);
else return query(l,m,z[rt].l,nowl,nowr);
}
else return query(m+1,r,z[rt].r,nowl,nowr);
}
int modify(int l,int r,int rt,int p,int v)//返回修改后的新节点编号
//当前线段树节点编号为rt 对应的区间为l~r 要把a[p]+=v
{
cnt++;int q = cnt;//新的节点q用于修改
z[q] = z[rt];
if (l==r)
{
z[q].sum += v;
return q;
}
int m=(l+r)>>1;
if (p<=m)//在左儿子
z[q].l = modify(l,m,z[q].l,p,v);
else
z[q].r = modify(m+1,r,z[q].r,p,v);
update(q);
return q;
}
int main()
{
cin >> n;
for (int i=1;i<=n;i++)
cin >> a[i];
cin >> m;
root[0] = build(1,n);//root[i]代表第i次操作后的根节点是谁
for (int i=1;i<=m;i++)
{
int opt;
cin >> opt;
if (opt==1)
{
int p,v;
cin >> p >> v;
root[i] = modify(1,n,root[i-1],p,v);
}
else
{
int k,l,r;
cin >> k >> l >> r;
cout << query(1,n,root[k],l,r) << "\n";
root[i] = root[i-1];
}
}
return 0;
}