您的位置:首页 > 其它

可持久化线段树 (模板)

2017-12-03 19:48 337 查看

对于历史版本只要从根节点入手即可,在修改的过程中再把这一时间的子树建出来。

时间复杂度O(qlog(n+q))。

#include<bits/stdc++.h>
using namespace std;
int cnt=0;
struct node
{
int l,r,v;
}t[20000005];
int a[1000005],rt[1000005];
void build(int &p,int l,int r)
{
p=++cnt;if(l==r){t

.v=a[l];return;} int m=(l+r)>>1; build(t[p].l,l,m);build(t[p].r,m+1,r); } void change(int &p,int x,int l,int r,int pos,int num) { p=++cnt;t[p].l=t[x].l;t[p].r=t[x].r;t[p].v=t[x].v; if(l==r){t[p].v=num;return ;} int m=(l+r)>>1; if(pos<=m)change(t[p].l,t[x].l,l,m,pos,num); else change(t[p].r,t[x].r,m+1,r,pos,num); } int query(int p,int l,int r,int pos) { if(l==r)return t[p].v; int m=(l+r)>>1; if(pos<=m)return query(t[p].l,l,m,pos); else return query(t[p].r,m+1,r,pos); } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]); build(rt[0],1,n); int tim,f,x,v; for(int i=1;i<=m;++i) { scanf("%d%d",&tim,&f); if(f==1){scanf("%d%d",&x,&v);change(rt[i],rt[tim],1,n,x,v);} else {scanf("%d",&x);printf("%d\n",query(rt[tim],1,n,x));rt[i]=rt[tim];} } return 0; }

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: