主席树

主席树/转自b站agoh

#include<iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + 5;
int a[maxn];
std::vector<int> v;
inline int getid(int x) { return lower_bound(v.begin(), v.end(), x) - v.begin() + 1; }
struct Node
{
    int l, r, sum;
}hjt[maxn * 40];
int cnt, root[maxn];
int n, m, l, r, k;
void insert(int l, int r, int pre, int& now, int p)
{
    hjt[++cnt] = hjt[pre];
    now = cnt;
    hjt[now].sum++;
    if (l == r) return;
    int m = (l + r) >> 1;       //>>1    =     /2
    if (p <= m) insert(l, m, hjt[pre].l, hjt[now].l, p);
    else insert(m + 1, r, hjt[pre].r, hjt[now].r, p);
}
int query(int l, int r, int L, int R, int k)
{
    if (l == r) return l;
    int m = (l + r) >> 1;
    int tmp = hjt[hjt[R].l].sum - hjt[hjt[L].l].sum;
    if (k <= tmp) return query(l, m, hjt[L].l, hjt[R].l, k);
    else return query(m + 1, r, hjt[L].r, hjt[R].r, k - tmp);
}
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin>>a[i],v.push_back(a[i]);
    std::sort(v.begin(), v.end());
    v.erase(std::unique(v.begin(), v.end()), v.end());
    for (int i = 1; i <= n; i++)
        insert(1, n, root[i - 1], root[i], getid(a[i]));
    while (m--)
    {
        cin >> l >> r >> k;
        cout << v[query(1, n, root[l - 1], root[r], k) - 1] << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cyq123/p/12799224.html