LUOGU P3919 【模板】可持久化數組(主席樹)
阿新 • • 發佈:2018-11-15
tchar printf 傳送門 org upd mat href show 數組
傳送門
解題思路
給每一時刻建一棵線段樹維護當前時刻的值,然後修改的時候直接修改,查詢的時候直接查,記住查詢完後一定要復制。
代碼
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; const int MAXN = 1000005; inline int rd(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {f=ch==‘-‘?0:1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} return f?x:-x; } int n,m,a[MAXN],rt[MAXN],cnt; int val[MAXN*22],ls[MAXN*22],rs[MAXN*22]; int build(int l,int r){ int now=++cnt,mid=(l+r)>>1; if(l==r) { val[now]=rd(); return now; } ls[now]=build(l,mid);rs[now]=build(mid+1,r); return now; } int update(int pre,int l,int r,int x,int k){ int now=++cnt,mid=(l+r)>>1; ls[now]=ls[pre];rs[now]=rs[pre];val[now]=val[pre]; if(l==r) {val[now]=k;return now;} if(x<=mid) ls[now]=update(ls[pre],l,mid,x,k); else rs[now]=update(rs[pre],mid+1,r,x,k); return now; } int query(int pre,int l,int r,int x){ if(l==r) return val[pre]; int mid=(l+r)>>1; if(x<=mid) return query(ls[pre],l,mid,x); else return query(rs[pre],mid+1,r,x); } int main(){ n=rd(),m=rd();rt[0]=build(1,n);int pre,op,x,y; for(int i=1;i<=m;i++){ pre=rd(),op=rd(),x=rd(); if(op==1) y=rd(),rt[i]=update(rt[pre],1,n,x,y); else printf("%d\n",query(rt[pre],1,n,x)),rt[i]=rt[pre]; } return 0; }
LUOGU P3919 【模板】可持久化數組(主席樹)