静态区间第k大,裸的主席树
直接上代码吧
#include<algorithm>
#include<cstdio>
using namespace std;
const int INF = 0x3f3f3f3f;
struct node{
int v;
int l,r;
void init(){
v = 0;
l = r = -1;
}
};
const int maxn = 112345;
const int maxlog = 20;
node arr[maxn*maxlog];
int head[maxn];
int _cnt;
int newnode(){
arr[_cnt].init();
return _cnt++;
}
int newtree(int l,int r){
int ret = newnode();
if(l == r){
return ret;
}
int m = (l + r)/2;
arr[ret].l = newtree(l,m);
arr[ret].r = newtree(m+1,r);
return ret;
}
int buildtree(int bef,int l,int r,int v){
int ret = newnode();
arr[ret] = arr[bef];
arr[ret].v++;
if(l == r){
return ret;
}
int m = (l+r) / 2;
if(v <= m) arr[ret].l = buildtree(arr[bef].l,l ,m,v);
else arr[ret].r = buildtree(arr[bef].r,m+1,r,v);
return ret;
}
int val[maxn];
void init(int n,int siz){
_cnt = 0;
head[0] = newtree(1,siz);
for(int i = 1;i<=n;i++){
head[i] = buildtree(head[i-1],1,siz,val[i]);
}
}
int req(int bef,int aft,int l,int r,int k){
if(l == r){
return l;
}
int siz = arr[arr[aft].l].v - arr[arr[bef].l].v;
int m = (l+r)/2;
if(k <= siz){
return req(arr[bef].l,arr[aft].l,l,m,k);
}
else{
return req(arr[bef].r,arr[aft].r,m+1,r,k-siz);
}
}
int msp[maxn],mlen;
int query(int l,int r,int k,int siz){
return msp[req(head[l-1],head[r],1,siz,k)];
}
int main(){
int T;
scanf("%d",&T);
int n,m;
while(T-- && ~scanf("%d %d",&n,&m)){
mlen = 0;
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
msp[mlen++] = val[i];
}
msp[mlen++] = -INF;
sort(msp,msp+mlen);
mlen = unique(msp,msp+mlen) - msp;
for(int i=1;i<=n;i++){
val[i] = lower_bound(msp,msp+mlen,val[i]) - msp;
}
init(n,mlen);
int l,r,k;
while(m--){
scanf("%d %d %d",&l,&r,&k);
printf("%d\n",query(l,r,k,mlen));
}
}
return 0;
}
1A真是太爽啦~