传送门:https://www.luogu.org/problemnew/show/P3834

题目描述

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

分析

很多人都说是用主席树来维护,一开始蒟蒻chh做这道题的时候还以为是分块乱搞,但是发现常数非常的大,就转用主席树了。这道题我们维护的主席树是一个权值线段树,意思就是维护一个桶,那么我们手动模拟主席树的建树过程,可以发现如果我们要查询区间\([l,r]\),那么发现编号为l-1的主席树和编号为r的主席树上对应的链上的差值就是我们区间上有多少个数是这样的。参照二叉搜索树的查找第k大的方法,我们就只需要每一次比较两个链上数值的差值和我们需要k大小,选择路径查询就可以做出来了。
注一句:这道题目因为维护的是权值线段树,那么题目中给出的1e9实在是太大了,那么我们就离散化一下,还是非常简单的。

ac代码

#include <bits/stdc++.h>
#define ll long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define N 200005
using namespace std;
template <typename T>
inline void read(T &x) {
    x = 0; T fl = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') fl = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= fl;
}
struct Last_segment_tree {
    #define mid ((l + r)>> 1)
    int tot;
    int rt[N];
    struct node {
        int lc, rc, s;
        node() {
            lc = rc = s = 0;
        }
    }tr[N * 35];
    Last_segment_tree() {
        tot = 0;
    }
    void build(int &nod, int l, int r) {
        nod = ++ tot;
        if (l == r) return;
        build(tr[nod].lc, l, mid);
        build(tr[nod].rc, mid + 1, r);
    }
    void update(int &nod, int pre, int l, int r, int k) {
        nod = ++ tot;
        tr[nod] = tr[pre]; tr[nod].s ++;
        if (l == r) return;
        if (k <= mid) update(tr[nod].lc, tr[pre].lc, l, mid, k);
        else update(tr[nod].rc, tr[pre].rc, mid + 1, r, k);
    }
    int query(int x, int y, int l, int r, int k) {
        if (l == r) return l;
        int a = tr[tr[y].lc].s - tr[tr[x].lc].s;
        if (a >= k) return query(tr[x].lc, tr[y].lc, l, mid, k);
        else return query(tr[x].rc, tr[y].rc, mid + 1, r, k - a);
    }
    int kth(int l, int r, int ql, int qr, int k) {
        return query(rt[ql - 1], rt[qr], l, r, k);
    }
}lstr;
int n, m;
int a[N], disc[N];
int main() {
    read(n); read(m);
    for (int i = 1; i <= n; i ++) {
        read(a[i]);
        disc[i] = a[i];
    }
    sort(disc + 1, disc + 1 + n);
    int d = unique(disc + 1, disc + 1 + n) - disc - 1;
    lstr.build(lstr.rt[0], 1, d);
    for (int i = 1; i <= n; i ++) {
        a[i] = lower_bound(disc + 1, disc + 1 + d, a[i]) - disc;
        lstr.update(lstr.rt[i], lstr.rt[i - 1], 1 , d, a[i]);
    }
    while (m --) {
        int x, y, z;
        read(x); read(y); read(z);
        int p = lstr.kth(1, d, x, y, z);
        printf("%d\n", disc[p]);
    }
    return 0;
}

[luogu3834]静态区间第k小【主席树】的更多相关文章

  1. Dynamic Rankings || 动态/静态区间第k小(主席树)

    JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...

  2. POJ2104 K-th Number —— 静态区间第k小

    题目链接:http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Sub ...

  3. 静态区间第K小(整体二分、主席树)

    题目链接 题解 主席树入门题 但是这里给出整体二分解法 整体二分顾名思义是把所有操作放在一起二分 想想,如果求\([1-n]\)的第\(k\)小怎么二分求得? 我们可以二分答案\(k\), \(O(n ...

  4. 主席树(可持久化线段树)静态区间第K小

    传送门主席树 #include <bits/stdc++.h> #define int long long using namespace std; const int maxn=2e5+ ...

  5. POJ2104&&HDU2665(静态区间第K小)

    题目大意 给定一个有N个数字的序列,然后又m个查询,形式如下: l r k 要求你返回区间[l,r]第k小的数是哪个 题解 终于弄懂主席树是个啥东西了,O(∩_∩)O~~,这题正是主席树的裸题,主席树 ...

  6. 洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)

    题目链接 //离散化后范围1~cnt不要错 #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  7. HDU2665 求区间第K大 主席树

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2665 代码: //#include<bits/stdc++.h> #include< ...

  8. 静态区间第k小 - 整体二分

    蒟蒻终于学会整体二分啦! 思路 实现 丑陋无比的代码 #include <bits/stdc++.h> using namespace std; const int N = 200005; ...

  9. POJ-2104-K-th Number(区间第K大+主席树模板题)

    Description You are working for Macrohard company in data structures department. After failing your ...

随机推荐

  1. java json字符串传递给 js 时 特殊字符转义错误 研究

    一些换行 回车等符号需要转义 主要注意 单引号 与双引号. 一 如果js以 双引号接收字符串 则转单引号 "  至 \" 否则js报错 二 如果js以 单引号接收字符串 则转单引号 ...

  2. 如何构造分层次的 Json 数据

    十年河东,十年河西,莫欺骚年穷...打错个字~_~ 现有如下需求,构造分层次的Json数据,层次结构类似下图: 上图使用EasyUI生成的,静态HTML如下: <html xmlns=" ...

  3. React + js-xlsx构建Excel文件上传预览功能

    首先要准备react开发环境以及js-xlsx插件 1. 此处省略安装react安装步骤 2.下载js-xlsx插件 yarn add xlsx 或者 npm install xlsx 在项目中引入 ...

  4. socket、tcp、udp、http 的认识及区别

    一.先来一个讲TCP.UDP和HTTP关系的 1.TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 在传输 ...

  5. Apache之Rewrite和RewriteRule规则梳理以及http强转https的配置总结

    一. 简单实例介绍一般来说,apache配置好http和https后,如果想要做http强转到https,需要设置url重定向规则,大致需要下面几个步骤即可完成配置: 1)在httpd.conf文件里 ...

  6. zabbix监控交换机、防火墙等网络设备

    zabbix3.4.4监控交换机/防火墙是非简单,只需知道交换机/防火墙的snmp密码,然后连接下自带或导入的snmp模板,就可以完成监控了.比如添加地址为172.10.11.5的交换机监控. 1)登 ...

  7. 牛客OI赛制测试赛-序列-模拟

    哇这道题好坑啊,可能是我太菜了 题意就是叫把一个连续序列分成K组,使得每个组的和都相等 我最开始的想法是由于要分成K组,那我们知道,每组一定有sum(a[i])/k这样我们只需要每次当num==sum ...

  8. 【Beta阶段】第九次Scrum Meeting!(论坛已成功上线)

    每日任务内容: 本次会议为第九次Scrum Meeting会议~ 本次会议为团队项目第九次会议,在会议前大家取得了重大成果! 队员 昨日完成任务 明日要完成任务 刘乾 #179 完成1021的数据处理 ...

  9. 《Linux内核分析》期终总结&《Linux及安全》期中总结

    <Linux内核分析>期终总结&<Linux及安全>期中总结 [李行之 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc. ...

  10. junit-test

    一.题目简介: 用单元测试junit4测试calculator类的加减乘除四种方法,来初步学习junit4的学习方法. 二.源码的github链接  :https://github.com/weare ...