可持久化线段树(主席树)
#include<stdio.h>
#define MAXN 100001
using namespace std;
int sum[MAXN*20],lson[MAXN*20],rson[MAXN*20];
int a[MAXN],root[MAXN];
int n,m,tot,now;
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || '9'<ch)
{
if (ch=='-')f=-1;
ch=getchar();
}
while ('0'<=ch && ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void maketree(int &t,int l,int r)
{
t=++tot;
if (l==r)
{
sum[t]=read();
return;
}
int mid=(l+r)/2;
maketree(lson[t],l,mid);
maketree(rson[t],mid+1,r);
sum[t]=sum[lson[t]]+sum[rson[t]];
}
void change(int old,int &t,int l,int r,int x,int y)
{
t=++tot;
lson[t]=lson[old],rson[t]=rson[old];
sum[t]=sum[old]+y;
if (l==r)return;
int mid=(l+r)/2;
if (x<=mid)change(lson[t],lson[t],l,mid,x,y);
else change(rson[t],rson[t],mid+1,r,x,y);
}
int query(int t,int l,int r,int x,int y)
{
if (x<=l && r<=y)return sum[t];
int mid=(l+r)/2,ans=0;
if (x<=mid)ans+=query(lson[t],l,mid,x,y);
if (y>mid)ans+=query(rson[t],mid+1,r,x,y);
return ans;
}
int main()
{
freopen("readin.txt","r",stdin);
n=read();
root[0]=1;
maketree(root[0],1,n);
m=read();
while (m--)
{
int w=read(),x=read(),y=read();
if (w==1)
{
now++;
change(root[now-1],root[now],1,n,x,y);
}
else
{
int z=read();
printf("%d\n",query(root[x],1,n,y,z));
}
}
return 0;
}