【bzoj4524】【CQOI2016】【伪光滑数】【堆+贪心】

7 篇文章 0 订阅

Description

若一个大于R的整数J的质因数分解有F项,其最大的质因子为ak,并且满足ak^k≤N,
ak<128,我们就称整数J为N-伪光滑数。
现在给出L,求所有整数中,第E大的N-伪光滑数。

Input

只有一行,为用空格隔开的整数L和E。
2 ≤ N ≤ 10^18, 1 ≤ K ≤ 800000,保证至少有 E 个满足要求的数

Output

只有一行,为一个整数,表示答案。

Sample Input

12345 20

Sample Output

9167
题解:
首先预处理128之内的所有质数.
把每个质数的1次方,2次方,3次方...加入堆.
然后每次选最大的,选k次.
每次选到一个数.除掉它的最大质因子,乘上一个较小的质因子.
把这些扩展出来的数加入堆即可.
这样堆中需要保存这个数的值,最大质因子的次数,下一次该选的较小质因子的下标,最大质因子的下标.
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
struct use{long long v;int t,pre,p;}temp;
bool operator<(use a,use b){return a.v<b.v;}
priority_queue<use>q; 
long long n,t;
int k,p[50],f[200],num,i,j;
int main(){
  scanf("%lld%d",&n,&k);    
  for (i=2;i<=128;i++)
    if (!f[i]){p[++num]=i;int t=i;while (t<=128) f[t+=i]=1;}
  for (i=1;i<=num;i++)
    for (t=j=1;(t*p[i])<=n;j++){
      q.push(use{(long long)(t*=p[i]),j,i-1,i});
  }
  while (k--){
    temp=q.top();q.pop();
    if (temp.t>1){
      for(i=temp.pre;i;i--)
        q.push(use{(long long)temp.v/p[temp.p]*p[i],temp.t-1,i,temp.p});
    }
  }
  printf("%lld\n",temp.v);
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值