【BZOJ 4524】【CQOI 2016】伪光滑数

本文介绍了一种使用优先队列和贪心算法解决质数分解问题的方法。通过找到所有小于128的质数,并利用这些质数及其幂次来构建可行方案。采用四元组表示方案,并不断更新队列,最终得到一个有效的质数分解结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

听说这道题标算是可持久化可并堆,但是用优先队列+贪心可以卡过去%%%。
首先找出所有小于128的质数,如果某个质数的q次方(q任取)小于n,那么这就是一个可行方案,加入优先队列。
接着每次取出一个方案,去掉一个质因数,加入一个较小的质因数,就形成了一个新的方案,加入队列,一直取k次即可。
具体实现方式是用一个四元组(x,i,j,k)表示一种方案,其中x表示当前的数;i那个最大的质因数的次数;j表示上一次加入的质因数,因为为了保证每一次方案不重复,加入的质因数必须越来越小;k表示最大的质因数。

#include<cmath>
#include<cstdio>
#include<vector>
#include <queue>
#include<cstring>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define N 20000
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct tuple{ll v; int t,pre,p;} g;
bool operator<(tuple a,tuple b){return a.v<b.v;}
priority_queue<tuple> q;
int i,j,k,sp;
ll n,t;
int f[N],p[N];
//当前数、最大质因数的次数、下一次选的质因数的下标的上限、最大质因数的下标
int main()
{
    scanf("%lld%d",&n,&k); 
    fo(i,2,128) if (!f[i]){p[++sp]=i;t=i;while(t<=128) f[t+=i]=1;}
    fo(i,1,sp)
        for (t = j = 1;(t * p[i]) <= n; j++)
            {
                t *= p[i];
                q.push(tuple{(ll)t,j,i-1,i});
            }


    while (k--)
        {
            g = q.top(); q.pop();
            if (g.t > 1)
                {
                    fd(i,g.pre,1)
                        {
                            ll u = g.v/p[g.p]*p[i];
                            q.push(tuple{(ll)u , g.t-1 , i , g.p});
                        }
                }
        }
    printf("%lld\n",g.v);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值