hdu6040 Hints of sd0061【nth_element使用】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6040
题意:给你一个函数,有一个长度为n的序列是由这个函数生成的,现在给你一个长度为m的序列,然你输出一个长度为m的东西,每一位表示a序列中第b[i]+1小的元素
解析:第一反应肯定是对a排序,但是快排复杂度是nlogn,而n的范围是不允许的,然后发现m又很小,所以从b序列入手,应该是个不错的选择,看了别人的博客发现了一个很有趣的STL,nth_element(arr.begin(),arr+n,arr.end()),调用这个函数后,会保证a[n]之前的元素都是小于a[n]的,而a[n]之后的元素都是大于a[n],这个函数的平均复杂度是线性的,如果把b序列从大到小来执行的,会不断缩小长度,所以理论上时间应该是符合的

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e7+100;
struct node
{
    int id,x;
    bool operator < (const node &b)const
    {
        return x>b.x;
    }
}b[maxn];
vector<pair<int,unsigned> >ans;
unsigned a[maxn];
unsigned x,y,z,A,B,C;
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;
}
int main(void)
{
    int n,m,case_t = 1;
    while(~scanf("%d %d %u %u %u",&n,&m,&A,&B,&C))
    {
        for(int i=0;i<m;i++)
        {
            scanf("%d",&b[i].x);
            b[i].id = i;
        }
        x = A,y = B,z = C;
        for(int i=0;i<n;i++)
            a[i] = rng61();
        sort(b,b+m);
        ans.clear();
        int last = n;
        for(int i=0;i<m;i++)
        {
            int now = b[i].x;
            nth_element(a,a+now,a+last);
            last = now;
            ans.push_back(make_pair(b[i].id,a[now]));
        }
        sort(ans.begin(),ans.end());
        printf("Case #%d:",case_t++);
        for(int i=0;i<m;i++)
            printf(" %u",ans[i].second);
        puts("");
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值