可持续化数组

可持续化数组

题意

保存更新数组的版本,并查询。

分析

【模板】可持久化线段树 1(可持久化数组)

代码


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];
		}
	}
}
posted @ 2020-08-04 10:39  王乾宇  阅读(98)  评论(0编辑  收藏  举报