zoukankan      html  css  js  c++  java
  • 洛谷 P3919 【模板】可持久化线段树 1(可持久化数组)

    洛谷 P3919 【模板】可持久化线段树 1(可持久化数组)

    洛谷传送门

    题目描述

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

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

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

    输入格式

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

    第二行包含NN个整数,依次为初始状态下数组各位的值(依次为 a_ia**i,1 leq i leq N1≤iN)。

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

    1. 对于操作1,格式为v_i 1 {loc}_i {value}iv**i 1 loc**i value**i,即为在版本v_iv**i的基础上,将 a{{loc}_i}aloci 修改为 {value}_ivalue**i
    2. 对于操作2,格式为v_i 2 {loc}iv**i 2 loc**i,即访问版本v_iv**i中的 a{{loc}_i}aloci的值,生成一样版本的对象应为vi

    输出格式

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


    题解:

    一道主席树的板子题,没学过的请走这边:

    详解主席树

    直接放代码:

    #include<cstdio>
    using namespace std;
    const int maxn=1e6+10;
    int n,m;
    int a[maxn],root[maxn];
    struct persistent_segment_tree
    {
        int lson,rson,val;
    }tree[maxn*24];
    int tot,ver;
    void build(int &pos,int l,int r)
    {
        int mid=(l+r)>>1;
        if(!pos)
            pos=++tot;
        if(l==r)
        {
            tree[pos].val=a[l];
            return;
        }
        build(tree[pos].lson,l,mid);
        build(tree[pos].rson,mid+1,r);
        tree[pos].val=tree[tree[pos].lson].val+tree[tree[pos].rson].val;
    }
    int newnode(int pos)
    {
        tree[++tot]=tree[pos];
        return tot;
    }
    int update(int pos,int l,int r,int x,int k)
    {
        int mid=(l+r)>>1;
        pos=newnode(pos);
        if(l==r)
        {
            tree[pos].val=k;
            return pos;
        }
        if(x<=mid)
            tree[pos].lson=update(tree[pos].lson,l,mid,x,k);
        else
            tree[pos].rson=update(tree[pos].rson,mid+1,r,x,k);
        return pos;
    }
    int query(int pos,int l,int r,int x)
    {
        int mid=(l+r)>>1;
        if(l==r)
            return tree[pos].val;
        if(x<=mid)
            return query(tree[pos].lson,l,mid,x);
        else
            return query(tree[pos].rson,mid+1,r,x);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build(root[0],1,n);
        while(m--)
        {
            int v,opt;
            int x,k;
            scanf("%d%d",&v,&opt);
            if(opt==1)
            {
                scanf("%d%d",&x,&k);
                root[++ver]=update(root[v],1,n,x,k);
            }
            else
            {
                scanf("%d",&x);
                root[++ver]=root[v];
                printf("%d
    ",query(root[v],1,n,x));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HTML5(一)初识HTML5
    iOS手机流量抓包rvictl
    mysql 安全模式
    DNS解析
    Git删除文件
    Git创建本地仓库并推送至远程仓库
    【python】字典/dictionary操作
    Gson解析复杂JSON字符串的两种方式
    apk安装提示:Failure [INSTALL_FAILED_DUPLICATE_PERMISSION perm=XXX]
    su、sudo、su
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13677998.html
Copyright © 2011-2022 走看看