HDU-6040 Hints of sd0061(线性找第k小)

来源:互联网 发布:朱元璋 知乎 编辑:程序博客网 时间:2024/06/07 09:49

传送门:HDU-6040

题意:给出n个数字,由m次查询,第i次查询问第b[i]小的数是多少

题解:线性找第k小

用到一个STL

nth_element(A, A + k, A+n)

表示在数组A的[0,n-1]中找到第k小的并放在第k个位置,并且前k-1个位置均为小于A[k]的数(要注意的一点就是:第k小中k是从0开始算的)

注意到在找到第k大的时候,前k-1个数均是小于A[k]的,这样我们从大往小枚举,可以减少搜索量


#include<bits/stdc++.h>using namespace std;typedef long long LL;const int MX = 1e7 + 5;struct node {    int k, id;    bool operator<(const node& _A)const {        return k < _A.k;    }} B[105];unsigned A[MX];int n, m, cas = 0;unsigned x, y, z, a, b, c, ans[105];unsigned cal() {    unsigned t;    x ^= x << 16; x ^= x >> 5; x ^= x << 1;    t = x; x = y; y = z;    z = t ^ x ^ y;    return z;}int main() {    //freopen("in.txt","r",stdin);    while (~scanf("%d%d%u%u%u", &n, &m, &a, &b, &c)) {        x = a; y = b; z = c;        for (int i = 0; i < m; i++) scanf("%d", &B[i].k), B[i].id = i;        for (int i = 0; i < n; i++) A[i] = cal();        sort(B, B + m);        B[m].id = m;        B[m].k = n;        for (int i = m - 1; i >= 0; i--) {            nth_element(A, A + B[i].k, A + B[i + 1].k);            ans[B[i].id] = A[B[i].k];        }        printf("Case #%d:", ++cas);        for (int i = 0; i < m; i++) printf(" %u", ans[i]);        printf("\n");    }    return 0;}