数据结构 - 主席树

查询 $[l,r]$ 区间第 $k$ 小的值。

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5;  //数据范围
int tot, n, m;
int sum[(maxn << 5) + 10], rt[maxn + 10], ls[(maxn << 5) + 10],
    rs[(maxn << 5) + 10];
int a[maxn + 10], ind[maxn + 10], len;
inline int getid(const int &val) { //离散化
    return lower_bound(ind + 1, ind + len + 1, val) - ind;
}
int build(int l, int r) { //建树
    int root = ++tot;
    if (l == r)
        return root;
    int mid = l + r >> 1;
    ls[root] = build(l, mid);
    rs[root] = build(mid + 1, r);
    return root;  //返回该子树的根节点
}
int update(int k, int l, int r, int root) { //插入操作
    int dir = ++tot;
    ls[dir] = ls[root], rs[dir] = rs[root], sum[dir] = sum[root] + 1;
    if (l == r)
        return dir;
    int mid = l + r >> 1;
    if (k <= mid)
        ls[dir] = update(k, l, mid, ls[dir]);
    else
        rs[dir] = update(k, mid + 1, r, rs[dir]);
    return dir;
}
int query(int u, int v, int l, int r, int k) { //查询操作
    int mid = l + r >> 1,
        x = sum[ls[v]] - sum[ls[u]];  //通过区间减法得到左儿子的信息
    if (l == r)
        return l;
    if (k <= x)  //说明在左儿子中
        return query(ls[u], ls[v], l, mid, k);
    else  //说明在右儿子中
        return query(rs[u], rs[v], mid + 1, r, k - x);
}
inline void init() {
    scanf("%d%d", &n, &m);
    for (register int i = 1; i <= n; ++i)
        scanf("%d", a + i);
    memcpy(ind, a, sizeof ind);
    sort(ind + 1, ind + n + 1);
    len = unique(ind + 1, ind + n + 1) - ind - 1;
    rt[0] = build(1, len);
    for (register int i = 1; i <= n; ++i)
        rt[i] = update(getid(a[i]), 1, len, rt[i - 1]);
}
int l, r, k;
inline void work() {
    while (m--) {
        scanf("%d%d%d", &l, &r, &k);
        printf("%d\n", ind[query(rt[l - 1], rt[r], 1, len, k)]);  //回答询问
    }
}
int main() {
    init();
    work();
    return 0;
}

原文地址:https://www.cnblogs.com/Yinku/p/10472880.html

时间: 2024-10-18 04:57:44

数据结构 - 主席树的相关文章

数据结构(主席树):HDU 5654 xiaoxin and his watermelon candy

Problem Description During his six grade summer vacation, xiaoxin got lots of watermelon candies from his leader when he did his internship at Tencent. Each watermelon candy has it's sweetness which denoted by an integer number. xiaoxin is very smart

数据结构(主席树):COGS 2213. K个串

2213. K个串 ★★★★   输入文件:bzoj_4504.in   输出文件:bzoj_4504.out   简单对比时间限制:20 s   内存限制:512 MB [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想知道,在这个数字序列所有连续的子串中,按照以上方式统计其所有数字之和,第 k大的和是多少. [输入格式] 第一行,两个整数n和k,分别表示长度为n

关于树状数组套主席树的一些博客

哇仿佛磕了几百年啊; 废话不多说,以下是帮助很大的一些blog: ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树) 主席树全纪录(这个很好) 主席树乱讲(没啥关系,不过有些题目可以刷??) 随笔分类 - 数据结构---主席树(同上) 原文地址:https://www.cnblogs.com/wwtt/p/10099695.html

可持久化数据结构之主席树

转自:http://finaltheory.info/?p=249 HomeACM可持久化数据结构之主席树 06十2013 可持久化数据结构之主席树 Written by FinalTheory on. Posted in ACM 引言 首先引入CLJ论文中的定义: 所谓的“持久化数据结构”,就是保存这个数据结构的所有历史版本,同时利用它们之间的共用数据减少时间和空间的消耗. 本文主要讨论两种可持久化线段树的算法思想.具体实现以及编码技巧. 核心思想 可持久化线段树是利用函数式编程的思想,对记录

【模板】【数据结构】【树】主席树

技巧一:离散去重 for(int i=1;i<=n;i++) scanf("%d",&a[i] ),b[i]=a[i]; sort(b+1,b+n+1); int nn=unique(b+1,b+n+1)-b-1;//假设有x个数,那么nn指针会停在第x+1个数的位置 ,nn及以后的都是重复的元素for(int i=1;i<=n;i++) id[i]=lower_bound(b+1,b+nn+1,a[i])-b;//离散过后的新value 技巧二:可持久化数据结构

数据结构(主席树):HZOI 2016 采花

[题目描述] 给定一个长度为n,包含c种颜色的序列,有m个询问,每次给出两个数l,r,表示询问区间[l,r]中有多少种颜色的出现次数不少于2次. 本题强制在线,对输入的l,r进行了加密,解密方法为: l = l' xor lastans r = r' xor lastans 其中l', r'为输入的l和r,xor表示异或,lastans为上一次询问的答案且初始值为0. [输入格式] 第一行三个正整数n,c,m,意义与题目描述中的相同. 第二行n个位于[1,c]内的正整数,表示序列上每个位置的颜色

数据结构之主席树

这里先讲静态的主席树,关于静态区间第k小.(有兴趣的朋友还可以去看看我写的整体二分,代码实现略优于主席树我觉得,当然静态主席树是很好写的) 题目描述: 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示序列的长度和查询的个数. 第二行包含N个正整数,表示这个序列各项的数字. 接下来M行每行包含三个整数 l, r, kl,r,k , 表示查询区间 [l, r][l,r] 内的第k小值. 输出格式: 输

【重码数据结构】主席树(可持久化线段树)

例题:https://www.luogu.org/problemnew/show/P3834 主席树用于查询每个历史版本. 这个题代码如下 #include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=200001; int n,m,tot; ll a[maxn],b[maxn]; struct stree{ int lc,rc; ll sum; #define lc(x) tree[x].lc

poj2104(主席树讲解)

今天心血来潮,突然想到有主席树这个神奇的玩意儿...一直都只是听说也没敢看.(蒟蒻蛋蛋的忧伤...) 然后到网上翻大神的各种解释...看了半天... 一拍脑袋...哇其实主席树 真的难...[咳咳我只是来搞笑的] 看了很多种解释最后一头雾水啊...就是没法脑补出(嗯没错经常脑补数据结构长啥样)主席树的样子.... 最后终于找到了一个大大大大大大神犇的ppt,看到了主席树的真面目,才真的能弄懂主席树的结构... -------------------------------------------