/* HDU 6040 - Hints of sd0061 [ 第k小数查询,剪枝 ] 题意: 给出随机数列 a[N] (N < 1e7) 询问 b[M] (M < 100) ,对于每个询问输出第 b[i]+1小的数字 满足对任意 i,j,k,若b[i] <= b[k] && b[j] <= b[k] 则一定有 b[i]+b[j] <= b[k] 分析: 用 nth_element() 解决第k小数问题 先将询问排序,可以从小到大或从大到小解决,就能每次不断缩小枚举区间 根据询问的限制条件,选择从大到小解决,这样每次剪去的区间至少是一半 */ #include <bits/stdc++.h> using namespace std; #define LL long long unsigned x, y, z; unsigned rng61() { unsigned t; x ^= x << 16; x ^= x >> 5; x ^= x << 1; t = x; x = y; y = z; z = t ^ x ^ y; return z; } const int N = 1e7+5; unsigned a[N]; unsigned A, B, C, n, m; void init() { x = A, y = B, z = C; for (int i = 0; i < n; i++) a[i] = rng61(); } struct Q{ int id, x; }q[105]; bool cmp(Q a, Q b) { return a.x < b.x; } unsigned ans[105]; int main() { int tt = 0; while (~scanf("%u%u%u%u%u", &n, &m, &A, &B, &C)) { for (int i = 0; i < m; i++) { scanf("%d", &q[i].x); q[i].id = i; } init(); sort(q, q+m, cmp); q[m].x = n; for (int i = m-1; i >= 0; i--) { if (q[i].x == q[i+1].x) { ans[q[i].id] = ans[q[i+1].id]; continue; } nth_element(a, a+q[i].x, a+q[i+1].x); ans[q[i].id] = a[q[i].x]; } printf("Case #%d:", ++tt); for (int i = 0; i < m; i++) printf(" %u", ans[i]); puts(""); } }