传送门: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;
}