1. 程式人生 > >洛谷3919:可持久化數組——題解

洛谷3919:可持久化數組——題解

isdigit getchar() targe namespace 就會 sdi pro ont pan

https://www.luogu.org/problemnew/show/P3919

如題,你需要維護這樣的一個長度為 N 的數組,支持如下幾種操作

  1. 在某個歷史版本上修改某一個位置上的值

  2. 訪問某個歷史版本上的某一位置的值

此外,每進行一次操作(對於操作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 namespace
std; 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:可持久化數組——題解