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 模板可持久化数组(可持久化线段树/平衡树)(入门第一题)

P3919 模板可持久化数组(可持久化线段树/平衡树)

[解题报告]P3919 模板可持久化数组(可持久化线段树/平衡树)

LUOGU P3919 模板可持久化数组(主席树)

主席树板子二