hdu6040 (nth_element函数)

题意:

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值