zoukankan      html  css  js  c++  java
  • 主席树浅谈

    静态主席树

    在谈什么是主席树之前,不得不提这个名字的来历……发明主席树的dalao首字母缩写为(HJT)正好是某位伟人的名字,因此得名主席树( ̄▽ ̄)/

    咳咳,现在我们正式介绍什么是主席树。


    主席树实际上是一种有点抽象的数据结构,它所维护的每一个节点都是一颗线段树,因此我们需要一个(root)数组用以记录每个根节点的编号。而它的线段树则是维护区间([1,i]),([1,i+1]),……的前缀,是一种可持久化数据结构,你可以查询它历史版本的信息,或者通过其可加,可减的性质完成对某区间的查找。

    例如想要查询第[l,r]区间的信息,那么,我们只需对(root[r]-root[l-1])求前缀和即可。

    显然,直接这样暴力对每个节点建树会MLE成傻子,但是我们动动脑筋就会发现:每次我们更新的仅仅是我们需要修改的点到根这条链上的信息,因此我们只需要重构这一条链,与上一个线段树相同的节点共用一下就行了。

    如图:

    这是我们的root[0],是一颗空树,接着我们加入一号元素(节点上的编号是其所属的线段树)

    就这样,我们就可以完成空间上的节省


    模板题静态区间第K小数

    code:

    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    struct node {
        int l,r,sum;
        node() {
            sum=0;//记录维护区间中的多少个数
        }
    } t[100005*40];
    
    int n,m,tot;
    int root[100005],a[100005];
    vector<int>v;
    
    int getid(int x)
    {
        return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
    }
    
    void modify(int l,int r,int &x,int y,int pos)
    {
        t[x=++tot]=t[y],t[x].sum++;
        if(l==r) return;
        int mid=l+r>>1;
        if(pos<=mid) modify(l,mid,t[x].l,t[y].l,pos);//小于mid找左子树
        else modify(mid+1,r,t[x].r,t[y].r,pos);//大于mid找右子树
    }
    
    int query(int l,int r,int x,int y,int k)
    {
        if(l==r) return l;
        int mid=l+r>>1;
        int del=t[t[y].l].sum-t[t[x].l].sum;
        if(k<=del) return query(l,mid,t[x].l,t[y].l,k);
        else return query(mid+1,r,t[x].r,t[y].r,k-del);//删除左子树贡献
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++) scanf("%d",&a[i]),v.push_back(a[i]);
        sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());//离散化
        for(int i=1; i<=n; i++) modify(1,n,root[i],root[i-1],getid(a[i]));
        while(m--) {
            int x,y,k;
            scanf("%d%d%d",&x,&y,&k);
            printf("%d
    ",v[query(1,n,root[x-1],root[y],k)-1]);//还原离散化的值
        }
    }
    

    动态主席树

    待填坑

  • 相关阅读:
    机器学习项目流程
    机器学习之数据归一化问题
    python三数之和
    从不订购的客户
    case when then的用法-leetcode交换工资
    .NET Core Api 集成 swagger
    .NET CORE 2.1 导出excel文件的两种方法
    Dapper的基本使用
    (转)深入研究MiniMVC之后续篇
    (转)深入研究 蒋金楠(Artech)老师的 MiniMvc(迷你 MVC),看看 MVC 内部到底是如何运行的
  • 原文地址:https://www.cnblogs.com/KatouKatou/p/9570963.html
Copyright © 2011-2022 走看看