2019多校第四场 HDU6623 Minimal Power of Prime(质因数分解,思维)

链接:HDU6623 Minimal Power of Prime

题意:

给出 T ( ≤ 50000 ) T(\le50000) T(50000) n ( ≤ 1 0 18 ) n(\le10^{18}) n(1018),对 n n n进行质因数分解,问分解后质因数的幂最小的是多少?

例如: 108 = 2 2 ∗ 3 3 108=2^2*3^3 108=2233,所以质因数的幂最小是 2 2 2



分析:

直接对 n n n进行质因数分解的话时间复杂度会达到 O ( T ∗ n 1 4 ) O(T*n^{\frac{1}{4}}) O(Tn41),会超时。

我们可以仅考虑 1 0 18 ∗ 1 5 10^{18*\frac{1}{5}} 101851,即 1 0 3.6 10^{3.6} 103.6以内的质因数进行考虑( 1 0 3.6 10^{3.6} 103.6内质数只有500多个),如果这些质因数最终没有将 n n n完全分解(没能令 n = 1 n=1 n=1),很明显 n n n剩下的可能质因数一定 > 1 0 3.6 \gt10^{3.6} >103.6,那么答案只有4种情况。

  1. n = p 4 n=p^4 n=p4,则ans=min(ans, 4)
  2. n = p 3 n=p^3 n=p3,则ans=min(ans, 3)
  3. n = p 2 或 n = p 1 2 ∗ p 2 2 n=p^2或n=p_1^2*p_2^2 n=p2n=p12p22,则ans=min(ans, 2)
  4. 除以上3种情况外,剩余的质因数幂最小一定为1,即ans=1


以下代码:

#include
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=4000;  //约等于10^3.6
int p[maxn],cnt=0;
bool vis[maxn];
void get_prime()      //欧拉筛得到质数表
{
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i])
            p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<=maxn;j++)
        {
            vis[i*p[j]]=true;
            if(i%p[j]==0)
                break;
        }
    }
}
int solve(LL x)
{
    if(x==1)
        return 0;
    int ans=INF,tot;
    for(LL i=1;i<=cnt;i++)
    {
        tot=0;
        while(x%(LL)p[i]==0)
        {
            tot++;
            x/=(LL)p[i];
        }
        if(tot==0)
            continue;
        ans=min(ans,tot);
        if(x==1)     //分解完成,说明所有质因数都在10^3.6以内
            return ans;
    }
    LL k;
    k=round(pow(1.0*x,1.0/4.0));
    if(k*k*k*k==x)
        return min(ans,4);
    k=round(pow(1.0*x,1.0/3.0));
    if(k*k*k==x)
        return min(ans,3);
    k=round(pow(1.0*x,1.0/2.0));
    if(k*k==x)
        return min(ans,2);
    return 1;
}
int main()
{
    get_prime();
    int T;
    scanf("%d",&T);
    while(T--)
    {
        LL n;
        scanf("%lld",&n);
        printf("%d\n",solve(n));
    }
    return 0;
}

你可能感兴趣的:(★水题之路,★2019HDU多校,★数学,#,【数论】)