[模板] 可持久化线段树(主席树)

洛谷P3834

教程视频

#pragma once
#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<complex>
#include<fstream>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<string>
#include<utility>
#include<vector>
#pragma warning(disable:4996 6031 6385 6386 6297 26451)
#define go(a,b,c,d) for(int a=b;a<=c;a+=d)
#define sgo(a,b) for(auto a:b)
#define lson root<<1
#define rson lson|1
#define Mid int m=((l+r)>>1)
#define ls lson,l,m
#define rs rson,m+1,r
#define rt 1,1,n
#define INF32 0x7f7f7f7f
#define INF64 0x7f7f7f7f7f7f7f7f
#define r(x) return x
#define rv return
#define pii pair<int,int>
#define pll pair<ll,ll>
#define int long long
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
template<typename T>
inline void read(T& x) {
    x = 0;
    int f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *= f;
}
template<typename T, typename ...Args>
inline void read(T& x, Args&... r) {
    read(x);
    read(r...);
}
struct A {
    int l, r, sum;
}MemPool[200001 * 50];
int n, m, a[200001], root[200001], cnt, l, r, k;
vector<int>v;
inline int GetID(int x) {
    return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}
inline void Insert(int &root, int lst, int l, int r, int v) {
    MemPool[++cnt] = MemPool[lst];
    root = cnt;
    ++MemPool[root].sum;
    if (l == r)
        rv;
    Mid;
    if (v <= m)
        Insert(MemPool[root].l, MemPool[lst].l, l, m, v);
    else
        Insert(MemPool[root].r, MemPool[lst].r, m + 1, r, v);
}
inline int Query(int l, int r, int tl, int tr, int k) {
    if (l == r)
        r(l);
    Mid;
    int tmp = MemPool[MemPool[tr].l].sum - MemPool[MemPool[tl].l].sum;
    if (k <= tmp)
        r(Query(l, m, MemPool[tl].l, MemPool[tr].l, k));
    r(Query(m + 1, r, MemPool[tl].r, MemPool[tr].r, k - tmp));
}
signed main() {
    read(n, m);
    go(i, 1, n, 1)
        read(a[i]),
        v.push_back(a[i]);
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    go(i, 1, n, 1)
        Insert(root[i], root[i - 1], 1, n, GetID(a[i]));
    while (m--) {
        read(l, r, k);
        cout << v[Query(1, n, root[l - 1], root[r], k) - 1] << endl;
    }
    return 0;
}

发表评论