洛谷3919:可持久化數組——題解
阿新 • • 發佈:2018-03-30
isdigit getchar() targe namespace 就會 sdi pro ont pan
https://www.luogu.org/problemnew/show/P3919
如題,你需要維護這樣的一個長度為 N 的數組,支持如下幾種操作
在某個歷史版本上修改某一個位置上的值
- 訪問某個歷史版本上的某一位置的值
此外,每進行一次操作(對於操作2,即為生成一個完全一樣的版本,不作任何改動),就會生成一個新的版本。版本編號即為當前操作的編號(從1開始編號,版本0表示初始狀態數組)
這題題意看錯了就很傷……操作2新建的版本是它所詢問的歷史版本emmm……
以及各種小錯誤,int沒return,y打成x,以及腦子抽了加了個k++。
總之做過BZOJ3673 & BZOJ3674 & 洛谷3402:可持久化並查集之後做這道題就很簡單啦。
我們開主席樹記錄修改和詢問就ok啦。
好像題解寫到這裏就沒了emmmm……
#include<cstdio> #include<queue> #include<cctype> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespacestd; const int N=1e6+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch==‘-‘;ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct tree{ int l,r,v; }tr[N*20]; int a[N],rt[N],n,m,pool; inline void build(int&x,int l,int r){ x=++pool; if(l==r){ tr[x].v=a[l]; return; } int mid=(l+r)>>1; build(tr[x].l,l,mid); build(tr[x].r,mid+1,r); } inline void modify(int y,int &x,int l,int r,int pos,int v){ tr[x=++pool]=tr[y]; if(l==r){ tr[x].v=v; return; } int mid=(l+r)>>1; if(pos<=mid)return modify(tr[y].l,tr[x].l,l,mid,pos,v); else modify(tr[y].r,tr[x].r,mid+1,r,pos,v); } inline int query(int x,int l,int r,int pos){ if(l==r)return tr[x].v; int mid=(l+r)>>1; if(pos<=mid)return query(tr[x].l,l,mid,pos); else return query(tr[x].r,mid+1,r,pos); } int main(){ n=read(),m=read(); for(int i=1;i<=n;i++)a[i]=read(); build(rt[0],1,n); for(int i=1;i<=m;i++){ rt[i]=rt[i-1]; int k=read(),op=read(); if(op==1){ int pos=read(),v=read(); modify(rt[k],rt[i],1,n,pos,v); } if(op==2){ int pos=read(); printf("%d\n",query(rt[k],1,n,pos)); rt[i]=rt[k]; } } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
洛谷3919:可持久化數組——題解