C49【模板】可持久化线段树(主席树)P3919 可持久化数组

视频链接:C49【模板】可持久化线段树(主席树)P3919 可持久化数组_哔哩哔哩_bilibili

 

 

 

 

 

Luogu P3919【模板】可持久化线段树1

//线段树+动态开点 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));
    }
  }
}

 

posted @ 2023-10-24 15:14  董晓  阅读(296)  评论(0编辑  收藏  举报