题意:
调用n次给出的函数,之后找第k小的数字,数据量到1e7,sort会t.因此可以简化sort(每次快排分治的位置如果是k就跳出)。这个想法有现成的函数nth_element。
思路:
具体的功能是 (start, start+n ,end)。把第n大的位置放在数组的n号位置。
之后从后往前扫,因为这样可以简化end的位置,加快速度,否则会TLE。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=10000005;
unsigned x,y,z,a[MAXN];
unsigned ans[105];
struct node
{
int num,id;
}num[105];
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;
}
bool cmp(node x,node y)
{
return x.num<y.num;
}
int main()
{
int n,m,i;
unsigned cas=1,A,B,C;
while(~scanf("%u%u%u%u%u",&n,&m,&A,&B,&C))
{
for(i=0;i<m;i++)
{
scanf("%d",&num[i].num);
num[i].id=i;
}
x=A; y=B; z=C;
for(i=0;i<n;i++)
a[i]=rng61();
sort(num,num+m,cmp);
num[m].id=m;
num[m].num=n;
for(i=m-1;i>=0;i--)
{
if(num[i].num==num[i+1].num&&i!=m-1)
ans[num[i].id]=ans[num[i+1].id];
else
{
nth_element(a,a+num[i].num,a+num[i+1].num);
ans[num[i].id]=a[num[i].num];
}
}
printf("Case #%u:",cas++);
for(i=0;i<m;i++)
printf(" %u",ans[i]);
printf("\n");
}
}