POJ--2104 K-th Number (主席树模版题)

题目链接

求区间第k大

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stdio.h>
using namespace std;
#define maxn 100009
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
struct ac{
   int va,l,r;
}tre[maxn*25];
int a[maxn],root[maxn],tot=0;
vector<int>q;
int getid(int x){
   return (lower_bound(q.begin(),q.end(),x)-q.begin()+1);
}
void updata(int l,int r,int &x,int y,int z){
   tre[++tot]=tre[y];
   tre[tot].va++;
   x=tot;
   if(l==r) return ;
   int mid=(l+r)/2;
   if(z>mid){
      updata(mid+1,r,tre[x].r,tre[y].r,z);
   }else updata(l,mid,tre[x].l,tre[y].l,z);
}
int query(int l,int r,int x,int y,int z){
  if(l==r) return l;
  int s=tre[tre[x].l].va-tre[tre[y].l].va;
  int mid=(l+r)/2;
  if(s>=z){
      return query(l,mid,tre[x].l,tre[y].l,z);
  }
  return query(mid+1,r,tre[x].r,tre[y].r,z-s);
}
int main(){
   int n,m;
   cin>>n>>m;
   mem(a,0); mem(tre,0);
   for(int j=1;j<=n;j++){
      scanf("%d",&a[j]);
      q.push_back(a[j]);
   }
   sort(q.begin(),q.end());
   q.erase(unique(q.begin(),q.end()),q.end());
   int len=q.size();
   for(int j=1;j<=n;j++){
       int x=getid(a[j]);
       updata(1,len,root[j],root[j-1],x);
   }
   for(int j=0;j<m;j++){
     int l,r,x;
     scanf("%d%d%d",&l,&r,&x);
     cout<<q[query(1,len,root[r],root[l-1],x)-1]<<endl;
   }
}

 

posted @ 2018-10-11 16:40  dingyl  阅读(114)  评论(0编辑  收藏  举报