C49【模板】可持久化线段树(主席树)P3919 可持久化数组
视频链接:C49【模板】可持久化线段树(主席树)P3919 可持久化数组_哔哩哔哩_bilibili
//线段树+动态开点 nlogn #include <iostream> using namespace std; #define N 1000005 #define mid ((l+r)>>1) int n,m,a[N]; int root[N],tot; //根节点,节点个数 int ls[N*25],rs[N*25],val[N*25]; void build(int &u,int l,int r){ //建树 u=++tot; //动态开点 if(l==r){val[u]=a[l]; return;} build(ls[u],l,mid); build(rs[u],mid+1,r); } void change(int &u,int v,int l,int r,int p,int x){ //点修 u=++tot; //动态开点 ls[u]=ls[v]; rs[u]=rs[v]; if(l==r){val[u]=x; return;} //双指针同步搜索 if(p<=mid) change(ls[u],ls[v],l,mid,p,x); else change(rs[u],rs[v],mid+1,r,p,x); } int query(int u,int l,int r,int p){ //点查 if(l==r) return val[u]; if(p<=mid) return query(ls[u],l,mid,p); else return query(rs[u],mid+1,r,p); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",a+i); build(root[0],1,n); for(int i=1;i<=m;i++){ int ver,op,p,x; scanf("%d%d",&ver,&op); if(op==1){ scanf("%d%d",&p,&x); change(root[i],root[ver],1,n,p,x); } else{ scanf("%d",&p); printf("%d\n",query(root[ver],1,n,p)); root[i]=root[ver]; } } }
//线段树+动态开点 nlogn #include <iostream> using namespace std; #define N 1000005 #define lc(u) tr[u].l #define rc(u) tr[u].r #define mid ((l+r)>>1) int n,m,a[N]; int root[N],tot; //根节点,节点个数 struct node{ int l,r,val; }tr[N*25]; void build(int &u,int l,int r){ //建树 u=++tot; //动态开点 if(l==r){tr[u].val=a[l]; return;} build(lc(u),l,mid); build(rc(u),mid+1,r); } void change(int &u,int v,int l,int r,int p,int k){ //点修 u=++tot; //动态开点 tr[u]=tr[v]; if(l==r){tr[u].val=k; return;} if(p<=mid) change(lc(u),lc(v),l,mid,p,k); else change(rc(u),rc(v),mid+1,r,p,k); } int query(int u,int l,int r,int p){ //点查 if(l==r) return tr[u].val; if(p<=mid) return query(lc(u),l,mid,p); else return query(rc(u),mid+1,r,p); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",a+i); build(root[0],1,n); for(int i=1;i<=m;i++){ int ver,op,p,k; scanf("%d%d",&ver,&op); if(op==1){ scanf("%d%d",&p,&k); change(root[i],root[ver],1,n,p,k); } else{ scanf("%d",&p); root[i]=root[ver]; printf("%d\n",query(root[ver],1,n,p)); } } }