POJ2104:K-th Number——题解

时间:2023-03-09 05:19:33
POJ2104:K-th Number——题解

http://poj.org/problem?id=2104

题目大意:求区间第k小。

——————————————————————————

主席树板子题。

……我看了半天现在还是一知半解的状态所以应该不会出讲解了。

#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct tree{
int l;
int r;
int sum;
}tr[N*];
int a[N],b[N],rt[N],n,m,q,pool;
inline void insert(int &y,int &x,int l,int r,int p){
tr[x=++pool]=tr[y];
tr[x].sum++;
if(l==r)return;
int mid=(l+r)>>;
if(p<=mid)insert(tr[y].l,tr[x].l,l,mid,p);
else insert(tr[y].r,tr[x].r,mid+,r,p);
return;
}
inline int query(int nl,int nr,int l,int r,int k){
if(l==r)return l;
int delta=tr[tr[nr].l].sum-tr[tr[nl].l].sum;
int mid=(l+r)>>;
if(delta>=k)return query(tr[nl].l,tr[nr].l,l,mid,k);
else return query(tr[nl].r,tr[nr].r,mid+,r,k-delta);
}
inline void LSH(){
m=n;
sort(b+,b+m+);
m=unique(b+,b+m+)-b-;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b+m+,a[i])-b;
}
return;
}
int main(){
n=read();
q=read();
for(int i=;i<=n;i++)a[i]=b[i]=read();
LSH();
for(int i=;i<=n;i++)insert(rt[i-],rt[i],,m,a[i]);
for(int i=;i<=q;i++){
int l=read(),r=read(),k=read();
printf("%d\n",b[query(rt[l-],rt[r],,m,k)]);
}
return ;
}