HDU 6040 Hints of sd0061(STL nth_element函数)

来源:互联网 发布:编程证书 编辑:程序博客网 时间:2024/06/15 19:06

题目:点击打开链接

题意:输入五个数值:n,m,a,b,c

n的用处为:调用n次题中给出的函数,生成一个长为n的数列

m为m次查询,每次查数组a里第bi小的数

a,b,c即所给函数中的x,y,z初值

要求依次输出查到的数

思路:这里用到一个STL的nth_element(a,a+k,a+last),该函数可以使得第k大元素在k位置上(下标从0开始),并且把比该元素小的元素放前面,大的元素放后面,但是不是排好序的,也就是说前后部分还是乱序。

注意重点是题中的这一条件:bi+bj<=bk is satisfied if bi≠bj, bi<bk and bj<bk,这样的话就要把查询数组的查询次序进行排序,先查大的,cmp函数为return b[x]>b[y]。这样可以每次把nth函数的last迅速缩短,避免TLE。

代码:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=1e7+7;int b[105],id[105];unsigned a[maxn],ans[105];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;}bool cmp(int x,int y){    return b[x]>b[y];}int main(){    ll n,m;    int id[102];    int cas=0;    while(~scanf("%lld%lld%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]);            id[i]=i;        }        sort(id,id+m,cmp);        int p,last=n;        for(int i=0;i<m;i++)        {            p=id[i];            nth_element(a,a+b[p],a+last);            ans[p]=a[b[p]];            last=b[p];        }        printf("Case #%d: ",++cas);        for(int i=0;i<m-1;i++)            printf("%u ",ans[i]);        printf("%u\n",ans[m-1]);    }    return 0;}


原创粉丝点击