求区间第k大。裸线段树。
莫队版本:☆
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #define lson l,m 7 #define rson m+1,r 8 using namespace std; 9 const int MAXN=100000+50; 10 int sum[MAXN<<5],L[MAXN<<5],R[MAXN<<5]; 11 int a[MAXN],hash[MAXN],T[MAXN],tot=0; 12 int m,n,d; 13 14 int build(int l,int r) 15 { 16 int rt=++tot; 17 sum[rt]=0; 18 if (l<r) 19 { 20 int m=(l+r)>>1; 21 L[rt]=build(lson); 22 R[rt]=build(rson); 23 } 24 return rt; 25 } 26 27 int update(int pre,int l,int r,int x) 28 { 29 int rt=++tot; 30 L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+1; 31 if (l!=r) 32 { 33 int m=(l+r)>>1; 34 if (x<=m) L[rt]=update(L[rt],lson,x); 35 else R[rt]=update(R[rt],rson,x); 36 } 37 return rt; 38 } 39 40 int query(int lrt,int rrt,int l,int r,int k) 41 { 42 if (l==r) return l; 43 int num=sum[L[rrt]]-sum[L[lrt]]; 44 45 int m=(l+r)>>1; 46 if(num>=k) 47 return query(L[lrt], L[rrt], lson, k); 48 else 49 return query(R[lrt], R[rrt], rson, k-num); 50 } 51 52 void init() 53 { 54 scanf("%d%d",&n,&m); 55 for (int i=1;i<=n;i++) 56 { 57 scanf("%d",&a[i]); 58 hash[i]=a[i]; 59 } 60 sort(hash+1,hash+n+1); 61 d=unique(hash+1,hash+n+1)-hash-1; 62 T[0]=build(1,n); 63 for (int i=1;i<=n;i++) 64 { 65 int x=lower_bound(hash,hash+d+1,a[i])-hash; 66 T[i]=update(T[i-1],1,d,x); 67 } 68 } 69 70 void solve() 71 { 72 for (int i=0;i<m;i++) 73 { 74 int l,r,k; 75 scanf("%d%d%d",&l,&r,&k); 76 int x=query(T[l-1],T[r],1,d,k); 77 printf("%d ",hash[x]); 78 } 79 } 80 81 int main() 82 { 83 init(); 84 solve(); 85 return 0; 86 }