题意
给出n个数字组成的数字序列,有m组询问。每次询问包含三个数字l,r,k。对于每个询问输出序列区间[l,r]中第k大的数字。
分析
这是主席树的模板题,套板子就可以
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 const int maxn=100000+10; 7 struct Value{ 8 int x; 9 int id; 10 bool operator <(const Value &rhs)const{ 11 return x<rhs.x; 12 } 13 }value[maxn]; 14 int n,m,num,cnt; 15 int lc[20*maxn],rc[20*maxn],sumv[20*maxn]; 16 int a[maxn],root[maxn],Rank[maxn]; 17 void update(int num,int old,int &o,int L,int R){ 18 o=++cnt; 19 lc[o]=lc[old],rc[o]=rc[old],sumv[o]=sumv[old]; 20 sumv[o]++; 21 if(L==R)return ; 22 int M=L+(R-L)/2; 23 if(num<=M)update(num,lc[o],lc[o],L,M); 24 if(num>M)update(num,rc[o],rc[o],M+1,R); 25 } 26 int query(int i,int j,int k,int L,int R){ 27 int lsum=sumv[lc[j]]-sumv[lc[i]]; 28 if(L==R)return L; 29 int M=L+(R-L)/2; 30 if(lsum>=k)return query(lc[i],lc[j],k,L,M); 31 else return query(rc[i],rc[j],k-lsum,M+1,R); 32 } 33 int main(){ 34 scanf("%d%d",&n,&m); 35 for(int i=1;i<=n;i++){ 36 scanf("%d",&a[i]); 37 value[i].x=a[i]; 38 value[i].id=i; 39 } 40 sort(value+1,value+1+n); 41 for(int i=1;i<=n;i++){ 42 Rank[value[i].id]=i; 43 } 44 num=1,cnt=0; 45 for(int i=1;i<=n;i++){ 46 update(Rank[i],root[i-1],root[i],1,n); 47 } 48 int l,r,k; 49 for(int i=1;i<=m;i++){ 50 scanf("%d%d%d",&l,&r,&k); 51 printf("%d ",value[query(root[l-1],root[r],k,1,n)].x); 52 } 53 return 0; 54 }