HDU 6231

(+フィートバイナリエミュレートされた)
の所定の長さ:イタリアこと N N < 105 配列 A そして、アレイを介してすべての長さより大きい K K N 最初のセクション、およびこれらのセクションの K 別の配列に大きい要素うち、革新的な第一世代のアレイ M 大きな要素とは何ですか。

アイデア:答えは肯定的であるので、このタイトルの開始点は、非常に重要です A 配列要素の一つ、及び A 以上のフロントファイナルランキング内の要素の大きいの確実性、あなたが半分答えを試すことができますので、その後、次は最初のランキングの新しい配列にこの要素のどのように多くのセクションを決定する方法を考える必要があり、その統計は徒歩でエミュレートしています K それが大きい場合よりも大きな要素は、それが解決することができます。

注意: M int型、および〜の書き込みの半分を超えてもよいです

コード:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long

using namespace std;
const int maxn = 100010;

int a[maxn], b[maxn];

LL get_rk(int x, int n, int k) {
    int r = -1;
    LL ret = 0, rk = 0;
    for(int l=0; l<n; l++) {
        while(rk < k && r < n) {
            rk += a[++r]>=x? 1:0;
        }
        if(rk >= k)
            ret += (LL)(n-r);
        rk -= a[l]>=x? 1:0;
    }
    //printf("x:%d ret:%I64d\n",x,ret);
    return ret;
}

void solve() {
    int n, k; LL m;
    scanf("%d%d%I64d",&n,&k,&m);
    for(int i=0; i<n; i++) {
        scanf("%d",&a[i]);
        b[i] = a[i];
    }
    sort(b, b+n);
    int l = 0, r = unique(b, b+n) - b - 1;
    while(l < r) {
        int mid = (l+r+1) / 2;
        if(get_rk(b[mid], n, k) >= m) l = mid;
        else r = mid - 1;
        //printf("l:%d r:%d\n",l,r);
    }
    printf("%d\n",b[l]);
}

int main() {
    int T;
    scanf("%d",&T);
    while(T --) {
        solve();
    }
    return 0;
}
公開された40元の記事 ウォン称賛44 ビュー90000 +

おすすめ

転載: blog.csdn.net/Site1997/article/details/78926694