• BZOJ 4524: [Cqoi2016]伪光滑数


    题意杀233,开始我习惯地认为质因数分解就是那种(2^{a_1} imes 3^{a_2} imes cdots imes p_k^{a_k})的形式,然后(p_k^{a_k})算作一项,苦想了30min无果

    然后看了下陈指导的博客,NMD原来上面的指数要展开的!(好吧这样本来也就是展开来的缩写),然后就会做了

    首先要求前(K)大,先考虑最大的情况。不难发现这个时候所有质因数都相同显然是最优的,因为如果不相同那么我们必然可以把不是最大的那些质因数全部换成最大的而满足(A_k^k)不变

    那么就很容易了,我们搞出(< 128)的所有质数,然后把它们的幂次都扔到堆里去,考虑如何更新答案

    由于现在的质因数都是相同的且最大的,那么我们肯定是在保证最大质因数项数不变的情况下让这个数本身变小,那么就是把其中的一个最大质因数换成更小的即可

    然后为了避免重复,我们还需要控制一个范围,表示枚举的替换的质因数的范围,同时还要保证替换之后这个最大质因数的幂次至少是(1)(废话)

    然后我们开一个四元组表示上面提到的状态即可

    #include<cstdio>
    #include<queue>
    #define RI register int
    #define CI const int&
    using namespace std;
    typedef long long LL;
    const int prime[31]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127};
    struct data
    {
        LL val; int prm,lim,tim; //当前值,最大质数,下个枚举的范围,这个质数的幂次
        friend inline bool operator < (const data& A,const data& B)
        {
            return A.val<B.val;
        }
    }; priority_queue <data> hp; LL n; int k;
    int main()
    {
        RI i,j; for (scanf("%lld%d",&n,&k),i=0;i<31;++i)
        for (LL cur=prime[i],ct=1;cur<=n;cur=cur*prime[i],++ct)
        hp.push((data){cur,prime[i],i-1,ct}); for (i=1;i<k;++i)
        {
            data now=hp.top(); hp.pop();
            if (now.tim>1) for (j=0;j<=now.lim;++j)
            hp.push((data){now.val/now.prm*prime[j],now.prm,j,now.tim-1});
        }
        return printf("%lld",hp.top().val),0;
    }
    
  • 相关阅读:
    事务
    javascript用window open的子窗口关闭自己并且刷新父窗口
    设置eclipse自动生成的author等注释
    使用Mockito对类成员变量进行Mock
    Linux进程简介
    WebSocket不同版本的三种握手方式以及一个Netty实现JAVA类
    长连接的定义及其优缺点,以及在不同的浏览器中的支持情况
    Sql为什么连接不上服务器上的数据库
    mysql批量导入已经格式好的文本数据
    Ant是什么
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12240851.html
Copyright © 2020-2023  润新知