POJ 2104 -- K-th Number

题目来源: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;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/81479334