• 【模板】可持久化线段树 1(主席树)


    题目描述

    如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值。

    输入输出格式

    输入格式:

    第一行包含两个正整数N、M,分别表示序列的长度和查询的个数。

    第二行包含N个正整数,表示这个序列各项的数字。

    接下来M行每行包含三个整数l, r, kl,r,k , 表示查询区间[l, r][l,r] 内的第k小值。

    输出格式:

    输出包含k行,每行1个正整数,依次表示每一次查询的结果

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 100005*2;
    int a[maxn], d, p[maxn];
    struct Node{
        int cnt;
        Node *ls, *rs;
        void up(){
            cnt = ls->cnt + rs->cnt;
        }
    }pool[maxn*32], *tail=pool, *root[maxn], *zero;
    void build(){
        zero = ++tail;
        zero->ls = zero->rs = zero;
        zero->cnt = 0;
        root[0] = zero;
    }
    Node * newnode(){
        Node * nd = ++tail;
        nd->ls = nd->rs = zero;
        nd->cnt = 0;
        return nd;
    }
    Node * modify(Node * nd, int pos, int del, int l = 1, int r = d){
        Node * nnd = newnode();
        if(l == r)nnd->cnt = nd->cnt + del;
        else{
            int m = (l + r) >> 1;
            if(pos <= m){
                nnd->rs = nd->rs;
                nnd->ls = modify(nd->ls, pos, del, l, m);
            }
            else{
                nnd->ls = nd->ls;
                nnd->rs = modify(nd->rs, pos, del, m+1, r);
            }
            nnd->up();
        }
        
        return nnd;    
    }
    
    int query(Node *lnd, Node *rnd, int k, int l = 1, int r = d){
        if(l == r)return a[l];
        int m = (l + r) >> 1;
        int lz = rnd->ls->cnt - lnd->ls->cnt;
        if(lz>= k)return query(lnd->ls, rnd->ls, k, l, m);
        else return query(lnd->rs, rnd->rs, k-lz, m+1, r);
    }
    int main(){
        int n,q;
        scanf("%d%d",&n,&q);
        for(int i = 1; i <= n; i++)scanf("%d",&a[i]),p[i]=a[i];
        sort(a+1, a+1+n);
        d = unique(a+1, a+1+n) - a - 1;
        build();
        for(int i = 1; i <= n; i++){
            int tt = lower_bound(a+1, a+1+d, p[i]) - a;
            root[i] = modify(root[i-1], tt, 1);
        } 
        while(q--){
            int l, r, k;
            scanf("%d%d%d",&l,&r,&k);
            printf("%d
    ",query(root[l-1], root[r], k));
        }
        
    }
  • 相关阅读:
    C++报错undefined reference to vtable处理
    emplace_back无法支持<braceenclosed initializer list>吗?
    使用proxychains代理应用
    EasyExcel快速读写Excel数据
    解决SpringBoot跨域的三种方式
    SQL Server 锁(LOCK)大全
    MySQL预处理语句PREPARE、EXECUTE、DEALLOCATE使用大全
    C# 自定义泛型二维数组
    C# 一维数组与二维数组相互转换
    C#枚举高级应用
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/8688521.html
Copyright © 2020-2023  润新知