P3919 模板可持久化数组(可持久化线段树/平衡树)
Posted qyj060604
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3919 模板可持久化数组(可持久化线段树/平衡树)相关的知识,希望对你有一定的参考价值。
P3919 【模板】可持久化数组(可持久化线段树/平衡树)
可持久化线段树
不过我对与这一道题有一个想法:
有没有一种可持久化的数组?
带着类似于可持久化线段树的新建节点的想法,我画下了图:
偶们得到了一个初始数组!
接下来修改:pos 1 val 14
那么我们这么做:
这样其实我们就可以On修改On查询了!
(那么优秀的O(n2)算法,怎么能不爆踩呢)
思考了一下,这个东西好像可以分块,类似这样:
修改都在块内进行,维护一下,可以On√n?
没实现,那位大佬发表一下集训队论文吧
接下来说正经的:
这道题就是一个裸的可持久化线段树
具体网上学
记住这题的ask操作也要生成一个版本,生成一个和他ask版本一毛一样的版本!
(我正纳闷:哪来10个版本!)
代码:
#include<bits/stdc++.h> using namespace std; const int N=1000005; struct node int l; int r; int lson; int rson; int val; ; int n,m; int a[N]; struct Sugment_Tree #define mid (l+r)/2 #define il inline int root[N]; node t[N<<4]; int cnt;//线段树节点数 int times;//几次版本 Sugment_Tree()cnt=0,times=0;memset(root,0,sizeof(root)); il int build(int l,int r) if(l==r) cnt++; t[cnt].val=a[l]; t[cnt].lson=-1; t[cnt].rson=-1; t[cnt].l=l; t[cnt].r=r; return cnt; cnt++; int y=cnt; t[y].lson=build(l,mid); t[y].rson=build(mid+1,r); t[y].val=0; t[y].l=l; t[y].r=r; return y; il int upt(node u,int pos,int X) if(u.l==u.r&&u.r==pos) cnt++; t[cnt]=u; t[cnt].val=X; return cnt; cnt++; int y=cnt; t[y]=u; node l=t[u.lson],r=t[u.rson]; if(l.l<=pos&&l.r>=pos) t[y].lson=upt(l,pos,X); t[y].rson=u.rson; if(r.l<=pos&&r.r>=pos) t[y].rson=upt(r,pos,X); t[y].lson=u.lson; return y; il int serch(node u,int pos) if(u.l==u.r&&u.r==pos) return u.val; node l=t[u.lson],r=t[u.rson]; if(l.l<=pos&&l.r>=pos) return serch(l,pos); if(r.l<=pos&&r.r>=pos) return serch(r,pos); return -10; T; int main() freopen("a.in","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); T.times++; T.root[1]=T.build(1,n); while(m--) int a,b,c,d; scanf("%d%d%d",&a,&b,&c); a++; if(b==1) scanf("%d",&d); T.times++; T.root[T.times]=T.upt(T.t[T.root[a]],c,d); else printf("%d\\n",T.serch(T.t[T.root[a]],c)); T.times++; T.root[T.times]=T.root[a]; return 0;
以上是关于P3919 模板可持久化数组(可持久化线段树/平衡树)的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)
P3919 模板可持久化数组(可持久化线段树/平衡树)(入门第一题)