洛谷 P3834 ——————【模板】可持久化线段树 1(主席树)

P3834 【模板】可持久化线段树 1(主席树)


#include
using namespace std;
const int MAXN = 2e5+7;
int n, m, cnt, rt[MAXN], a[MAXN], x, y, k;
struct node{int l,r,sum;} T[MAXN*30];
vector<int> v;
int getid(int x) { return lower_bound(v.begin(), v.end(), x) - v.begin() + 1; }
void update(int l, int r, int &x, int y, int pos) {
        T[++cnt] = T[y]; T[cnt].sum++; x = cnt;
        if(l==r)        return ;
        int mid = (l+r)>>1;
        if(mid>=pos)    update(l, mid, T[x].l, T[y].l, pos);
        else            update(mid+1, r, T[x].r, T[y].r, pos);
}
int query(int l, int r, int x, int y, int k) {
        if(l == r)      return l;
        int sum = T[T[y].l].sum - T[T[x].l].sum;
        int mid = (l+r)>>1;
        if(sum>=k)      return query(l, mid, T[x].l, T[y].l, k);
        else            return query(mid+1, r, T[x].r, T[y].r, k - sum);
}

int main() {
        v.clear(); cnt = 0;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;++i)   scanf("%d",&a[i]), v.push_back(a[i]);
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        for(int i=1;i<=n;++i) update(1, n, rt[i], rt[i-1], getid(a[i]));
        for(int i=1;i<=m;++i) {
                scanf("%d %d %d",&x,&y,&k);
                printf("%d\n",v[query(1, n, rt[x-1], rt[y], k)-1]);
        }

        return 0;
}

你可能感兴趣的:(主席树)