zoukankan      html  css  js  c++  java
  • 数据结构

    查询 $[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
    ", ind[query(rt[l - 1], rt[r], 1, len, k)]);  //回答询问
        }
    }
    int main() {
        init();
        work();
        return 0;
    }
  • 相关阅读:
    Hibernate的注释该如何使用?每一个注释代表什么意思?
    J2SE总结(一)-------容器
    解决hibernate向mysql插入中文乱码问题(更改MySQL字符集)
    android程序员成长路径的思考
    Fragment总结
    onCreateView的一个细节--Fragment
    屏幕适配
    表驱动法3
    表驱动法2
    表驱动法1
  • 原文地址:https://www.cnblogs.com/Yinku/p/10472880.html
Copyright © 2011-2022 走看看