题意:
构造出一个数组,查询整个数组第k大。
思路:可以运用nth_element函数,nth_element函数是把第k大的数放在第k位,然后左边都是比它小的数,右边都是比它大的数,顺序任意。
为了更优化一些,先将要查询的数列排个序,然后从后往前进行查询,因为输入保证任意两个小的之和小于第三个
所以查询数列的间隔一定大于等于斐波那契,也就是从大到小查询的话,每次至少能去掉一半的区间.
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 9;
unsigned x ,y, z ;
inline 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;
}
unsigned a[maxn];
int b[110];
unsigned ans[110];
int pos[110];
bool cmp(int x,int y)
{
return b[x] < b[y];
}
int main()
{
int n,m;
int T = 1;
while( ~ scanf("%d%d%u%u%u",&n,&m,&x,&y,&z))
{
for(int i = 0; i < n;++ i)
{
a[i] = rng61();
}
for(int i = 0; i < m; i ++)
scanf("%d",&b[i]),pos[i] = i;
sort(pos,pos + m,cmp);//因为最后要按输入顺序输出,所以用下标对查询数组进行排序
printf("Case #%d:",T ++);
b[pos[m] = m] = n;
for(int i = m - 1; i >= 0; -- i)
{
if(b[pos[i] ] == b[pos[i + 1]])
{
ans[pos[i]] = ans[pos[i + 1]];continue;
}
nth_element(a,a + b[pos[i] ],a + b[pos[i + 1] ]);//不用到最后
ans[pos[i]] = a[b[pos[i]] ];
}
for(int i = 0; i < m;++ i)
printf(" %u",ans[i]);
printf("\n");
}
return 0;
}