Poj 2104 K-th Number 主席树模版题

题意:离线询问[l,r]区间第k大

题解:模版题,入门题

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#include <cstring>
#include <iomanip>
#include <set>
#include<ctime>
//CLOCKS_PER_SEC
#define se second
#define fi first
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define Pii pair<int,int>
#define Pli pair<ll,int>
#define ull unsigned long long
#define pb push_back
#define fio ios::sync_with_stdio(false);cin.tie(0)
const double Pi=3.14159265;
const int N=1e5+10;
const ull base=163;
const int INF=0x3f3f3f3f;
using namespace std;
int n,m,cnt,root[N],k,x,y;
struct node {
    int l,r,sum;
}T[40*N];
int a[N];
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 m=(l+r)>>1;
    if(pos<=m)update(l,m,T[x].l,T[y].l,pos);
    else update(m+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 m=(l+r)>>1;
    int d=T[T[y].l].sum-T[T[x].l].sum;
    if(d>=k)  return  query(l,m,T[x].l,T[y].l,k);
    else  return query(m+1,r,T[x].r,T[y].r,k-d);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);v.pb(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,root[i],root[i-1],getid(a[i]));
    while(m--){
        int l,r,k;scanf("%d%d%d",&l,&r,&k);
        printf("%d
",v[query(1,n,root[l-1],root[r],k)-1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Mrleon/p/9097694.html