其实我觉得这方法效率真心不高…
poj 2104 K-th Number
这题我照着模板写t了,网上的ac代码用了11秒,先挂上吧…

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstdlib>
#include<string>
#include<vector>
#include<list>
#include<map>
#include<set>
#define fi first
#define se second
#define pb push_back
#define me(a,b) memset(a,b,sizeof(a))
#define INIT() std::ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>P;
const int MAX_N=100000+5;
const int MAX_M=100000+5;
const int INF=0x7fffffff;
const int inf=1000000000;
const double EPS=1e-6;
const ull base=123;
const ll mod=998244353;
const double pi=4*atan(1.0);
int a[MAX_N];
int num[MAX_N];
int B=1000;
vector<int>v[300];
int main()
{
   
    int n,m;
    scanf("%d%d",&n,&m);
    int i;
    for(i=0;i<n;i++)
    {
   
        scanf("%d",&a[i]);
        num[i]=a[i];
        v[i/B].pb(a[i]);
    }
    sort(num,num+n);
    for(i=0;i<n/B;i++)
    {
   
        sort(v[i].begin(),v[i].end());
    }
    while(m--)
    {
   
        int l,r,k;
        scanf("%d%d%d",&l,&r,&k);
        l--;
        int left=0;
        int right=n-1;
        int mid=(left+right)>>1;
        while(left<=right)
        {
   
            int x=num[mid];
            int tl=l;
            int tr=r;
            int c=0;
            while(tl<tr&&tl%B)
            {
   
                if(a[tl++]<=x)c++;
            }
            while(tl<tr&&tr%B)
            {
   
                if(a[--tr]<=x)c++;
            }
            while(tl<tr)
            {
   
                int b=tl/B;
                c+=upper_bound(v[b].begin(),v[b].end(),x)-v[b].begin();
                tl+=B;
            }
            if(c>=k)
                right=mid-1;
            else
                left=mid+1;
            mid=(left+right)>>1;
            //cout<<mid<<endl;
        }
        printf("%d\n",num[mid+1]);
    }
}