hdu6040 (nth_element函数)

来源:互联网 发布:淘宝什么叫直通车 编辑:程序博客网 时间:2024/06/10 20:03

题意:

构造出一个数组,查询整个数组第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;}