• 2019杭电多校赛第四场 HDU6623 Minimal Power of Prime 素数


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6623

    题意:输出将一个数n(1e18)质因数分解后其所有质因数幂的最小值

    分析:首先,质因数分解中,一个数的所有质因数都会参与构成这个数

    n最大是1e18的情况下,单独处理前1e4的,前1e4的处理完后如果发现n还不是1,说明它还有质因数,而且这个质因数肯定是大于1e4的了,而大于1e4的质因数幂取值就只有4,3,2,1这四种了,分别看n^(1/4),n^(1/3),n^(1/2)是不是整数就好,如果都不是就肯定是1了。

    简而意之,先处理1e4以内的质数,也就1000多个,然后如果没有除尽的话,因子最多也就4个了,所以幂数大于1的情况有p1^4,p1^3, p1^2 , p1^2*p2^2,  对于其他情况肯定有幂为1的。

    代码有较为详细的注释

    另外推荐一个快速质因数分解的方法,本题没用到,但还是很有用的https://blog.csdn.net/Asher_S/article/details/81867146

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    const int maxn=1e4+7;
    const ll inf=1e18+7;
    const double pi=acos(-1);
    int num,pri[maxn];
    void init(){//这个函数用来求1e4的质数有哪些 
        int lim;
        for(int i=2;i<maxn;i++){
            if(!pri[i]) pri[num++]=i;
            for(int j=0;j<num;j++){
                lim=i*pri[j];
                if(lim>=maxn) break;
                pri[lim]=1;
                if(i%pri[j]==0) break;
            }
        }
    }
    ll three(ll n){
        ll l=1,r=pow(n*1.0,1.0/3)+1,mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(mid*mid*mid==n) return mid;
            else if(mid*mid*mid>n) r=mid-1;
            else l=mid+1;
        }
        return -1;    
    }
    
    ll solve(ll n){
        int ans=100,res;//ans用来记录最后结果,初始化大一点 
        for(int i=0;i<num;i++){
            if(1ll*pri[i]*pri[i]>n)break;//说明接下来的质因数不可能是n的质因数了 
            if(n%pri[i]==0){
                res=0;
                while(n%pri[i]==0){
                res++;
                n/=pri[i];
                }
                ans=min(ans,res);
            }
            if(ans==1) return 1;//如果在这一步便取到了最小值1,1e4之后的数据就不用管了,直接返回 
        }
        //这个循环求出了n的四分之一次幂前的质因数的答案,接下来开始求剩下的部分,剩下部分不可能超过四次幂,
        //因为他们都大于1e4,即便n取最大1e18也顶多四次 
        if(n>1){//n不为1说明其还有质因数,且1e4前面的都已经处理了,只能是1e4后的质因数 
            ll kg1=sqrt(n),kg2;//判断是否为整数 
            if(kg1*kg1==n){
                kg2=sqrt(kg1);
                if(kg2*kg2==kg1){
                    if(ans>4) ans=4;
                }
                else if(ans>2) ans=2;
            }
            else{
                kg1=three(n);//求出三次根号下的n 
                if(kg1*kg1*kg1==n&&ans>3) ans=3;
                else ans=1;//都不满足的话就为1 
            }
        }
        return ans;
    }
    int main(){
        int T;cin>>T;
        init(); 
        while(T--){
            ll n; scanf("%lld",&n);
            printf("%lld
    ",solve(n));
        }
        return 0;
    }
  • 相关阅读:
    wmq的A×B Problem
    MATLAB 求系统的单位冲击响应及单位阶跃响应
    关于共享率过低的一些事
    Vue组件之间的通信
    浏览器支持ES6的import和export
    Vue axios拦截问题
    开屏倒计时
    git常用操作
    原型
    this指向问题
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11280582.html
Copyright © 2020-2023  润新知