主席树

 

随意写写,勿介意

P3834 - 洛谷

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define R register
using namespace std;
typedef long long ll;
const ll N=200010;
ll n,m,cnt;
ll a[N],b[N];
inline void discretize(){
    sort(b+1,b+n+1);
    cnt=unique(b+1,b+n+1)-b-1;
}
ll sum[N*40],lc[N*40],rc[N*40],rt[N*40],sz;
inline void build_empty(ll &rt,ll l,ll r){
    rt=++sz;
    sum[rt]=0;
    if(l==r) return ;
    ll mid=(l+r)>>1;
    build_empty(lc[rt],l,mid);
    build_empty(rc[rt],mid+1,r);
}
inline ll update(ll x,ll l,ll r,ll p){
    ll xx=++sz;
    lc[xx]=lc[x],rc[xx]=rc[x],sum[xx]=sum[x]+1;
    if (l==r) return xx;
    ll mid=(l+r)>>1;
    if(p<=mid) lc[xx]=update(lc[x],l,mid,p);
    else rc[xx]=update(rc[x],mid+1,r,p);
    return xx;
}
inline ll query(ll u,ll v,ll l,ll r,ll kth){
    ll mid=(l+r)>>1;
    ll x=sum[lc[u]]-sum[lc[v]];
    if(l==r) return l;
    if(kth<=x) return query(lc[u],lc[v],l,mid,kth);
    else return query(rc[u],rc[v],mid+1,r,kth-x);
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(R ll i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        b[i]=a[i];
    }
    discretize();
    ll h;
    build_empty(rt[0],1,cnt);
    for(R ll i=1;i<=n;i++){
        h=lower_bound(b+1,b+cnt+1,a[i])-b;
        rt[i]=update(rt[i-1],1,cnt,h);
    }
    ll x,y,z;
    for(R ll i=1;i<=m;i++){
        scanf("%lld%lld%lld",&x,&y,&z);
        printf("%lld\n",b[query(rt[y],rt[x-1],1,cnt,z)]);
    }

}

注意要开N*40

 

posted @ 2020-07-29 21:44  愚者123  阅读(82)  评论(0)    收藏  举报