• 2019HDU多校Minimal Power of Prime——分段讨论&&思维


    题目

    将 $n$($1 < n leq 10^{18}$)质因数分解,求质因数幂的最小值。

    分析

    直接质因数分解,不太行。

    可以这样想,对小区间质因数分解,n变小了,再枚举答案。

    打印1-10000之间的素数表然后质因数分解,分解完剩下的那个数,

    • 两种质数(肯定大于 $10^4$)相乘,最多二次,合起来也是一个平方数;
    • 三种或以上质数相乘,只可能为一次,不用考虑。
    • 一种质数,最多为四次方,枚举四、三、二次方,如果都不是,就是单个质数

    要注意:先看是4次方再看2次方(因为如果满足4次方一定满足2次方,但是满足4次方也满足2次方,2次方的话就不是质因数了),3次方无所谓,因为开3次方会损失精度,所以就二分一下。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    ll n;
    
    //返回n以内素数的个数
    //埃氏筛法O(nloglogn)
    const int maxn = 100000 + 10;
    int prime[maxn];            //prime[i]表示第i个素数
    bool is_prime[maxn + 1];    //is_prime[i]为true表示i是素数
    
    int sieve(int n)
    {
        int cnt = 0;
        for (int i = 0; i <= n; i++)  is_prime[i] = true;
        is_prime[0] = is_prime[1] = false;
        for (int i = 2; i <= n; i++)
        {
            if (is_prime[i])
            {
                prime[cnt++] = i;
                for (int j = i * i; j <= n; j += i)  is_prime[j] = false;  //i * i可能爆int
            }
        }
        return cnt;
    }
    
    bool is_three(ll n)    //是否能开立方
    {
        ll l = 10000, r = 1e6;
        while(l <= r)
        {
            ll mid = (l+r) >> 1;
            ll tmp = mid*mid*mid;
            if(tmp == n)  return true;
            else if(tmp > n) r = mid-1;
            else l = mid+1;
        }
        return false;
    }
    
    int main()
    {
        int cnt = sieve(10000);  //筛出10000内的质数
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%lld", &n);
            int ans = 100;
            for(int i = 0;i < cnt;i++)
            {
                if(n % prime[i] == 0)
                {
                    int tmp = 0;
                    while(n % prime[i] == 0)
                    {
                        n /= prime[i];
                        tmp++;
                    }
                    ans = min(tmp, ans);
                }
                if(n == 1) break;
            }
            if(ans == 1){ printf("1
    "); continue;}
            if(n == 1){ printf("%d
    ", ans); continue;}
    
            ll t1 = (ll)sqrt(n);
            ll t2 = (ll)sqrt(t1);
            if(t2*t2*t2*t2 == n)  ans = min(ans, 4);
            else if(t1*t1 == n)  ans = min(ans, 2);
            else if(is_three(n))  ans = min(ans , 3);
            else ans = min(ans, 1);
            printf("%d
    ", ans);
        }
        return 0;
    }

    参考链接:https://blog.csdn.net/lgz0921/article/details/97948432

  • 相关阅读:
    页面实现的平滑效果
    CSS :hover 选择器
    AngularJS 路由
    [Leetcode] Container With Most Water
    [Leetcode] Minimum Path Sum
    [Leetcode] Unique Paths II
    [Leetcode] Unique Paths
    [Leetcode] Maximum Subarray
    [Leetcode] Binary Tree Postorder Traversal
    [Leetcode] Binary Tree Preorder Traversal
  • 原文地址:https://www.cnblogs.com/lfri/p/11290356.html
Copyright © 2020-2023  润新知