首先可知答案的数字具有一定的单调性。考虑使用二分答案的方式。
如何验证:已知这个数字,去区间里面找有多少个数比当前这个数字大,如果数量大于等于m的话证明该数小了,需要向右移动反之向左移动。
在统计区间里面有多少个数比当前的数字大的时候,要注意使用双指针的方式,否则会超时。还有就是要用long long。
//双指针加二分做法。
#include <bits/stdc++.h>
typedef long long ll;

using namespace std;
const int maxn = 1e5+10;
ll N, K, M;
ll a[maxn];

bool yanz(ll x)
{
    ll num=0,s=0;
    for(int i=1,j=1;j<=N;j++)
    {
        if(a[j]>=x) num++;///值大于X
        if(num==K)///出现k个值大于等于X
        {
            s+=N-j+1;///将右边界大于等于j的区间都算上
            while(a[i]<x) s+=N-j+1,i++;///左边界右移 如果num没少 又加一次右边界等于大于j的区间
            num--;i++;///这个左边界值大于X
        }
    }
    return s>=M;
}


int main() {
    int T, max;
    scanf("%d", &T);
    while (T--) {
        scanf("%lld %lld %lld", &N, &K, &M);
        for (int i=1;i<=N;i++) {
            scanf("%lld", a+i);
            max = max>a[i]? max:a[i];
        }
        //二分答案
        ll l = 1, r = 1e9, ans=0;
        while (l<r) {
            ll mid = (l+r+1)/2;
            if (yanz(mid)) {
                ans = mid;
                l = mid;
            }
            else r = mid-1;
        }
        printf("%lld\n", ans);
//         cout<<yanz(8)<<endl;
    }
    
    
    return 0;
}