题目来源:http://poj.org/problem?id=2104
平方分割做法。效率不是很高,TLE了好几次才勉强过去。
注意在处理区间的时候最好要用左闭右开的区间。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=1e5+10;
const int B=750;
int a[maxn],num[maxn],n,q;
vector<int> v[maxn/B+10];
int main() {
scanf("%d%d", &n, &q);
for (int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
v[i / B].push_back(a[i]);
num[i] = a[i];
}
sort(num, num + n);
for (int i = 0; i < n / B; ++i)
sort(v[i].begin(), v[i].end());
while(q--) {
int cl, cr, k;
scanf("%d%d%d", &cl, &cr, &k);
cl--;
int l = -1, r = n - 1;
while (l < r - 1) {
int mid = (l + r) / 2, x = num[mid], c = 0, tl = cl, tr = cr;
while (tl < tr && tl % B != 0) {
if (a[tl] <= x)++c;
tl++;
}
while (tl < tr && tr % B != 0) {
tr--;
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)r = mid;
else l = mid;
}
printf("%d\n", num[r]);
}
return 0;
}