• luogup3834(主席树模板)


    luogup3834(主席树模板)

    给定由N个正整数构成的序列,将对于指定的闭区间查询m次其区间内第k小值。1≤N,M≤2e5。

    有一个做法,是对于每个序列的前缀建一颗权值线段树,然后通过权值线段树相减得到的权值线段树来查询第k小值。由于单点修改只需要改动logn个结点,第i个主席树可以依托第i-1个存在。具体的做法是将路径上的点从上到下依次克隆一遍。时间复杂度和空间复杂度都是nlogn。

    #include <cctype>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=2e5+5, maxstree=maxn*60;
    struct node{
        int l, r, x;
    }stree[maxstree];
    
    //a:离散化后的序列 b:离散化的数对应的值
    int n, m, a[maxn], b[maxn], cntu;
    //cntnode:主席树一共有几个结点
    int cntnode=1, root[maxn];  //root:第i棵线段树的根的位置
    
    //在主席树的当前区间[l, r)中插入值为v的结点
    //now位置的结点会被拷贝一份生成新的结点
    void insert(int &now, int l, int r, int v){
        stree[cntnode]=stree[now]; now=cntnode;  //(此处一举两得,既更新了父节点的孩子编号,又把操作转到了被复制的节点)
        ++stree[cntnode++].x;
        if (l==r-1) return;
        int mid=(l+r)>>1;
        if (v<mid) insert(stree[now].l, l, mid, v);
        else insert(stree[now].r, mid, r, v);
    }
    
    //在区间[l, r)中,定位第k大数
    int query(int now1, int now2, int l, int r, int k){
        if (l==r-1) return l;
        int t=stree[stree[now2].l].x-stree[stree[now1].l].x, mid=(l+r)>>1;
        if (k<=t) return query(stree[now1].l, stree[now2].l, l, mid, k);
        else return query(stree[now1].r, stree[now2].r, mid, r, k-t);
    }
    
    inline void get(int &x){
        char c; int flag=1;
        for (; c=getchar(), !isdigit(c); )
            if (c=='-') flag=-1;
        for (x=c-48; c=getchar(), isdigit(c); )
            x=(x<<3)+(x<<1)+c-48; x*=flag;
    }
    
    int main(){
        get(n); get(m);
        for (int i=0; i<n; ++i){ get(a[i]); b[i]=a[i]; }
        sort(b, b+n); cntu=unique(b, b+n)-b;
        for (int i=0; i<n; ++i) a[i]=lower_bound(b, b+cntu, a[i])-b;
        for (int i=0; i<n; ++i){ root[i+1]=root[i]; insert(root[i+1], 0, n, a[i]); }
        int t1, t2, t3;
        while (m--){
            get(t1); get(t2); get(t3);
            printf("%d
    ", b[query(root[t1-1], root[t2], 0, n, t3)]);
        }
        return 0;
    }
    
  • 相关阅读:
    tomcat简介与配置
    gitlab简介与配置
    cobbler自动装机服务简介与配置
    Linux中管理员用户与普通用户之间的切换
    kafka 学习
    Linux系统swappiness参数在内存与交换分区之间优化作用
    CentOS7中使用yum安装Nginx的方法
    配置两个Hadoop集群Kerberos认证跨域互信
    Linux shell中2>&1的含义解释
    解决SpringBoot多工程时jar包中注解不能扫描生效问题
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/8575479.html
Copyright © 2020-2023  润新知