• [模板] 可持久化数组


    题目背景

    UPDATE : 最后一个点时间空间已经放大

    标题即题意

    有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集)

    题目描述

    如题,你需要维护这样的一个长度为 N的数组,支持如下几种操作

    1. 在某个历史版本上修改某一个位置上的值

    2. 访问某个历史版本上的某一位置的值

    此外,每进行一次操作(对于操作2,即为生成一个完全一样的版本,不作任何改动),就会生成一个新的版本。版本编号即为当前操作的编号(从1开始编号,版本0表示初始状态数组)

    输入输出格式

    输入格式:

    输入的第一行包含两个正整数 N,M, 分别表示数组的长度和操作的个数。

    第二行包含 N个整数,依次为初始状态下数组各位的值

    接下来 M行每行包含3或4个整数,代表两种操作之一( i 为基于的历史版本号):

    1. 对于操作1,格式为 (v_i) 1 (loc_i) (val_i),即为在版本(v_i)的基础上,
      (a_{loc_i})​​ 修改为​

    2. 对于操作2,格式为(v_i) 2 (loc_i),即访问(v_i)版本(loc_i)的值。

    输出格式:

    输出包含若干行,依次为每个操作2的结果。

    说明

    (1≤n≤10^6,1≤m≤10^6,1≤loc_i≤n,0≤v_i≤i,-10^9≤a_i,val_i≤10^9)

    Solution

    主席树模板,直接上代码。

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int a[1001000],b[1000100],root[1100000];
    int tot=0;
    struct NODE
    {
        int ln,rn,val;
    }t[20100000];
    void build(int &node,int l,int r)
    {
        
        node=++tot;
        if(l==r) {t[node].val=a[l];return;}
        int mid=(l+r)/2;
        build(t[node].ln,l,mid);
        build(t[node].rn,mid+1,r);
    }
    void gai(int &node,int last,int l,int r,int kk,int val)
    {
        node=++tot;t[node]=t[last];
        if(l==r) {t[node].val=val;return;}
        int mid=(l+r)/2;
        if(kk<=mid) gai(t[node].ln,t[last].ln,l,mid,kk,val);
        else gai(t[node].rn,t[last].rn,mid+1,r,kk,val);
    }
    int cha(int node,int l,int r,int kk)
    {
    //	printf("%d %d %d %d
    ",node,l,r,kk);
        if(l==r) return t[node].val;
        int mid=(l+r)/2;
        if(kk<=mid) return cha(t[node].ln,l,mid,kk);
        else return cha(t[node].rn,mid+1,r,kk);
    }
    int main()
    {
        int n,m,k;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        build(root[0],1,n);
        for(int i=1;i<=m;i++)
        {
            int a1,a2,a3,a4;
            scanf("%d%d%d",&a1,&a2,&a3);
            if(a2==1)
            {
                scanf("%d",&a4);
                gai(root[i],root[a1],1,n,a3,a4);
            }
            else
            {
                printf("%d
    ",cha(root[a1],1,n,a3));
                root[i]=root[a1];
            }
        }
    }
    
  • 相关阅读:
    检验maven的配置是否生效或正确。
    CTO、技术总监和技术经理有啥区别?
    WinScp自动执行脚本
    宝塔--服务器运维面板
    Tomcat中给server.xml加入<Context>元素
    Tomcat之Session名称修改-springboot
    修改tomcat默认的session时间
    Shiro权限框架简单快速入门
    mybatis关联查询
    <mvc:default-servlet-handler/>导致controller失效,报404错误
  • 原文地址:https://www.cnblogs.com/kzj-pwq/p/9376323.html
Copyright © 2020-2023  润新知