zoukankan      html  css  js  c++  java
  • [SDOI2005]反素数ant

    原题链接:https://www.luogu.org/problemnew/show/P1463

    题目大意:在[1,n]的范围内,求一个数,要求所有小于这个数的数因数个数也要小于这个数,n<=2e9

    设m=a1^p1*a2^p2……ak^pk

    m的约数个数为(p1+1)*(p2+1)……(pk+1)

    luogu题解上的dalao们都没给证明,但是其实很好证啊。。。

    设num是m的一个因数,可以有0,1...pi个ai算进num中,即有pi+1种选法,因为ai都是质因数,所以互不影响,所以实际因数个数就是个乘法原理。。。

    因为2^31>2e9 所以p1+p2+...pk<31

    能够证明,符合条件的数字,它的质因数分解一定是由a1开始连续的

    num=a1^p1*a2^p2...ak^pk  (p1*p2*p3*...*pk>0)

    因为如果不是这样,则必定有一个数,将其中的一个ai换为更小的pi=0的ai,num一定会变小,但是(p1+1)*(p2+1)……(pk+1)却不会变,原数不合要求。

    而最多10个质因子的乘积就会超过2e9,所以枚举质因子时只需枚举10个就够了。(不过为了保险,我用了15个)

    然后枚举选用的质因子和它们的指数,搜索即可。

    #include<cstdio>
    int pre[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
    long long n,maxn,ans,sum;
    void dfs(long long p,long long a,int x)
    {
        if(p>maxn)
        {
            maxn=p;
            ans=a;
        }
        if(p==maxn&&ans>a) ans=a;
        if(x>15) return;
        for(int i=1;i<=34;i++)
        {
            if(a*pre[x]>n) break;
            dfs(p*(i+1),a*pre[x],x+1);
            a*=pre[x];
        }
    }
    int main()
    {
        scanf("%lld",&n);
        ans=n;
        dfs(1,1,1);  
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    ubuntu+VS code+launch.json+task.json
    C++——运行时类型识别RTTI
    C++——模板
    C++——class类和struct结构体的唯一区别
    C++——右值引用
    C++——智能指针
    身份证号码格式检测
    PHP获取图片主题颜色
    PHP 压缩图片质量
    redis3.2装完后 其它机子访问爆protocol error, got 'n' as reply type byte
  • 原文地址:https://www.cnblogs.com/zeroform/p/8337800.html
Copyright © 2011-2022 走看看