主席树

Posted cyq123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了主席树相关的知识,希望对你有一定的参考价值。

主席树/转自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;
}

 

以上是关于主席树的主要内容,如果未能解决你的问题,请参考以下文章

代码源 Div1 - 108#464. 数数(主席树,区间比k小的数的个数)HDU4417

主席树学习记录

Yangk's 静态主席树-模板

bzoj2809 [ APIO2012 ] -- 主席树

主席树

主席树 模板