【GDUT】Problem A: 第k大(STL之nth_element()函数)

Time Limit: 1 Sec Memory Limit: 128 MB
Description
求第k大的数,比如{1,2,3,4,5} 第1大的为5,第2大的为4….第5大的为1

为了节省IO时间,输入数据采用如下函数生成,n,A,B,c是输入,res是输出数列,n表示要生成数列的个数。
void Create(long long res[],int n,unsigned int A, unsigned int B, unsigned int c){

for(int i=0;i<n;i++){
    res[i]=A+B;
    A=((A<<2)+c)*i*29+B;
    B=(((A+B)<<3)+c)*17;
}

}

Input
第一行输入一个T,共有T组测试数据,每组一行
n A B c k
T<20 k<=n<=1e6,sum of n<=1e7 A,B,c<1e9
Output
每行输出一个数,第k大答案,详看下面样例
Sample Input
10
10 4 5 999 1
10 4 5 999 2
10 4 5 999 3
10 4 5 999 4
10 4 5 999 5
10 4 5 999 6
10 4 5 999 7
10 4 5 999 8
10 4 5 999 9
10 4 5 999 10
Sample Output
3994101628
3977009663
3285558082
3280200307
2923342952
1891986542
1717397513
9073109
18348
9

分析:
求序列中第k大的元素,当序列长度n不大时,可以用快排(O(nlogn)或者优先队列(O(klogn))实现小顶堆,而本题中n,k最大为1e6, 用以上方法都会T
这里用到了STL中的 nth_element(start,start+first,start+last);这个函数仅对[first,last]内的数进行排序。
它的用法见:
http://blog.csdn.net/xiaoquantouer/article/details/51591140
http://blog.csdn.net/smf0504/article/details/51426750

代码:

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

#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i<n;i++) ///[a,n)
#define pb push_back
#define IO ios::sync_with_stdio(false)
#define fre freopen("in.txt","r",stdin)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const double PI=acos(-1.0);
const double E=2.718281828459045;
const double eps=1e-8;
const int INF=0x3f3f3f3f;
const int MOD=1e8+7;
const int N=1e6+5;
const ll maxn=1e6+5;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
const ll inf=0x3f3f3f3f3f3f3f3f;

ll ans[N];
ll T,n,a,b,c,k;
bool cmp(ll a,ll b)
{
    return a>b;
}
void Create(uint a,uint b,uint c)
{
    for(int i=0; i<n; i++)
    {
        ans[i]=a+b;
        a=((a<<2)+c)*i*29+b;
        b=(((a+b)<<3)+c)*17;
    }
    nth_element(ans,ans+n-k,ans+n);
    printf("%lld\n",ans[n-k]);
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d",&n,&a,&b,&c,&k);
        Create(a,b,c);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值