LightOJ 1220 Mysterious Bacteria(唯一分解定理)

Dr. Mob has just discovered a Deathly Bacteria. He named it RC-01. RC-01 has a very strange reproduction system. RC-01 lives exactly x days. Now RC-01 produces exactly p new deadly Bacteria where x = bp (where b, p are integers). More generally, x is a perfect pth power. Given the lifetime x of a mother RC-01 you are to determine the maximum number of new RC-01 which can be produced by the mother RC-01.


Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case starts with a line containing an integer x. You can assume that x will have magnitude at least 2 and be within the range of a 32 bit signed integer.

Output

For each case, print the case number and the largest integer p such that x is a perfect pth power.

Sample Input

3

17

1073741824

25

Sample Output

Case 1: 1

Case 2: 30

Case 3: 2

分析:给你一个整数n(可能为负数),让你求满足a^p=n的最大的p,

当n是正数时,直接对n进行素因子分解,n=p1^e1*p2^e2*......pk*ek,

p1,p2...pk为素数,那么p=gcd(e1,e2,...ek);

当n为负数时,p不能为偶数,那么就把上面的p一直除以2,直到为奇数为止。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int p[65536],a[65536],cnt=1;
int s[65536],sum;
void prime()
{
    for(int i=4;i<65536;i+=2) a[i]=1;
    p[0]=2;
    for(int i=3;i<65536;i++)
    {
        if(!a[i])
        {
            p[cnt++]=i;
            for(int j=i+i;j<65536;j+=i) a[i]=1;
        }
    }
}

int gcd(int x,int y)
{
    int r;
    while(y)
    {
        r=x%y;
        x=y;
        y=r;
    }
    return x;
} 

int f(long long N)
{
    int flag=0;
    if(N<0) {flag=1;N=-N;}
    sum=0;s[0]=0;
    for(int i=0;i<cnt&&p[i]*p[i]<=N;i++)
    {
        if(N%p[i]!=0) continue;
        while(N%p[i]==0)
        {
            s[sum]++;N/=p[i];
        }
        sum++;s[sum]=0;
    }
    if(N>1) return 1;
    int ans=99999;
    for(int k=1;k<=sum;k++)
    {
        ans=min(gcd(s[k],s[k-1]),ans);
        
    }
    
    if(flag&&ans%2==0)
    {
        while(ans%2==0) ans/=2;
        return ans;
    }
    else return ans;
}

int main()
{
    int T,cas=0;long long N;
    scanf("%d",&T);
    prime();
    while(T--)
    {
        scanf("%lld",&N);
        printf("Case %d: %d
",++cas,f(N));    
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ACRykl/p/8667023.html