可持续化数组
可持续化数组
题意
保存更新数组的版本,并查询。
分析
代码
const int maxn=20000006;
struct kkk
{
int l,r,val;
}tree[maxn];//建树
int top,a[maxn],n,m,root[maxn],rt[maxn];
int clone(int node)
{
top++;
tree[top]=tree[node];
return top;
}//更新线段树不再是直接更新,而是新建一个树再更新
int maketree(int node,int begin,int end)
{
node=++top;
if(begin==end)
{
tree[node].val=a[begin];//到达叶子节点,有一个值
return top;
}
int mid=(begin+end)>>1;
tree[node].l=maketree(tree[node].l,begin,mid);//不是叶子节点就要存储新建的树的左右儿子
tree[node].r=maketree(tree[node].r,mid+1,end);
return node;
}
int update(int node,int begin,int end,int x,int val)
{
node=clone(node);//新建更新节点,克隆后已经有了历史版本的左右儿子。
if(begin==end)//到达叶子节点
{
tree[node].val=val;
}
else
{
int mid=(begin+end)>>1;
if(x<=mid)
{
tree[node].l=update(tree[node].l,begin,mid,x,val);//x小于mid就要更新左儿子
}
else
{
tree[node].r=update(tree[node].r,mid+1,end,x,val);
}
}
return node;
}
int query(int node,int begin,int end,int x)
{
if(begin==end)
{
return tree[node].val;
}
else
{
int mid=(begin+end)>>1;
if(x<=mid)
return query(tree[node].l,begin,mid,x);
else
return query(tree[node].r,mid+1,end,x);
}
}
main(void)
{
int mode,x,y,rt;;
n=read();
m=read();
for(int i=1;i<=n;i++)a[i]=read();
root[0]=maketree(0,1,n);
for(int i=1;i<=m;i++)
{
rt=read(),mode=read(),x=read();
if(mode==1)
{
y=read();
root[i]=update(root[rt],1,n,x,y);
}
else
{
printf("%d\n",query(root[rt],1,n,x));
root[i]=root[rt];
}
}
}