hdu6040 Hints of sd0061

本文解析了一道关于快速查找第k小元素的问题,利用nth_element及排序技巧,在大规模数据集上实现了高效求解。通过分析题目特点,采用特殊排序策略和k-d树思想解决传统排序无法应对的大规模查询问题。

http://acm.hdu.edu.cn/showproblem.php?pid=6040

这题题意也不太说人话。。。而且前期过的人太少了,最后一小时看懂了发现其实是一道很水的题

他的意思就是随机给你生成一堆数字,然后询问m次第bj+1小的是多大

n=1e7,T=10,m=100,所以排序nlogn*T直接1e9了,肯定不行的

那么这题的关键问题就是把你排序给卡了怎么快速的回答第bj+1小的值是哪个

了解k-d树这个东西后,我们可以知道区间第k大如果只需要知道值的话可以用nth_element这个东西来搞(2018我校校赛热身赛甚至出了个必须用fread和nth_element才能过的题。。。)

那么题目还给出了一个奇怪的条件,也就是如果存在bi<bk,bj<bk,且bi!=bj,那么bi+bj<=bk,就说明对于不同的两个值,要大于他们的值一定要比他们之和还大,那么b数组就是一个2次幂级别增大的东西,只需要排序,从大到小,每次nth_element一下前缀就行,因为nth_element会把第bj+1大的放到bj+1的位置,左边都是小于它的,右边都是大于他的,但是是无序的,具体内部实现我好像还不会。。。

那么由于区间是不断/2的,那么总共的区间长度之和最多就是2n

#include<bits/stdc++.h>
using namespace std;

const int maxl=1e7+10;

int n,m,cas;
unsigned A,B,C,a[maxl],ans[110];
struct node
{
	int val,id;
}b[110];

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;
}

inline bool cmp(const node &a,const node &b)
{
	if(a.val==b.val)
		return a.id<b.id;
	return a.val<b.val;
}

inline void prework()
{
	scanf("%u%u%u",&A,&B,&C);
	for(int i=1;i<=m;i++)
		scanf("%d",&b[i].val),b[i].id=i;;
	sort(b+1,b+1+m,cmp);
	x = A, y = B, z = C;
	for(register int i=1;i<=n;++i)
		a[i]=rng61();
	int last=n;
	for(int i=m;i>=1;i--)
	{
		if(i+1<=m && b[i+1].val==b[i].val)
		{
			ans[b[i].id]=a[b[i].val+1];
		}
		else
		{
			nth_element(a+1,a+b[i].val+1,a+1+last);
			ans[b[i].id]=a[b[i].val+1];
			last=b[i].val+1;
		}
	}
}

inline void mainwork()
{
	
}

inline void print()
{
	++cas;
	printf("Case #%d:",cas);
	for(int i=1;i<=m;i++)
		printf(" %u",ans[i]);
	puts("");
}


int main()
{
	int t=1;
	while(~scanf("%d%d",&n,&m))
	{
		prework();
		mainwork();
		print();
	}
	return 0;
} 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值