zoukankan      html  css  js  c++  java
  • P3834 【模板】可持久化线段树 (静态主席树)

    主席树查找和更新时时间空间复杂度均为O(logn),建树2*nlogn, 且空间复杂度约为O(nlogn + nlogn)前者为空树的空间复杂度,后者为更新n次的空间复杂度

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn],v[maxn],rt[maxn],tot,n,nn,q;
    struct node
    {
        int ls,rs,sum;
        node(int ls=0,int rs=0,int sum=0)
        {
            this->ls=ls,this->rs=rs,this->sum=sum;
        }
    }tree[maxn*30];
    
    int build1(int l,int r)
    {
        int t=++tot;
        tree[t].sum=0;
        if(l!=r)
        {
            int mid=(l+r)>>1;
            tree[t].ls=build1(l,mid);
            tree[t].rs=build1(mid+1,r);
        }
        return t;
    }
    int build2(int l,int r,int last,int val)
    {
        int t=++tot;
        tree[t]=tree[last];
        tree[t].sum++;
        if(l!=r)
        {
            int mid=(l+r)>>1;
            if(val<=mid)
                tree[t].ls=build2(l,mid,tree[last].ls,val);
            else
                tree[t].rs=build2(mid+1,r,tree[last].rs,val);
        }
        return t;
    }
    int query(int l,int r,int x,int y,int k)
    {
        if(l==r) return l;
        int tmp=tree[tree[y].ls].sum-tree[tree[x].ls].sum,mid=(l+r)>>1;
        if(tmp>=k)
            return query(l,mid,tree[x].ls,tree[y].ls,k);
        else
            return query(mid+1,r,tree[x].rs,tree[y].rs,k-tmp);
    }
    int getval(int x)
    {
        return lower_bound(v+1,v+nn+1,x)-v;
    }
    int main(){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
            scanf("%d",&(a[i])),v[i]=a[i];
        sort(v+1,v+n+1);
        nn=unique(v+1,v+n+1)-v-1;
        rt[0]=build1(1,nn);
        for(int i=1;i<=n;i++)
            rt[i]=build2(1,nn,rt[i-1],getval(a[i]));
        while(q--)
        {
            int x,y,k;
            scanf("%d%d%d",&x,&y,&k);
            printf("%d
    ",v[query(1,nn,rt[x-1],rt[y],k)]);
        }
        return 0;
    }
    

    学了之后才发现,可持久化线段树就是把1到n每个位置都开了一个权值线段树(每个权值线段树都代表了1至i这个版本的信息),也没想象的那么难。

  • 相关阅读:
    (原)ubuntu16在torch中使用caffe训练好的模型
    (原)Ubuntu16中卸载并重新安装google的Protocol Buffers
    (原)lua提示cannot load incompatible bytecode
    (原)ubuntu上安装nvidia及torch的nccl
    Ubuntu修改grub菜单引导选项和等待时间
    Servelet 简介
    JAVA JUC 线程池
    JAVA JUC synchronized 锁的理解
    JAVA JUC 读写锁
    JAVA JUC 线程按顺序执行
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754771.html
Copyright © 2011-2022 走看看