Mysterious Bacteria LightOJ - 1220 唯一分解定理

问题:

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

题意:x=b^p  给出x求出最小的p。

用到的定理:唯一分解定理:每一个大于1的正整数n都可以唯一地写成素数的乘积,在乘积中的素因子按照非降序排列,正整数n的分解式n=(p1^α1)*(p2^α2)*(p3^α3)* .......*(pk^αk)称为n的标准分解式,其中p1,p2,p3......pk是素数,p1<p2<p3.....,且α1,α2,α3.......是正整数。

思路:利用上述定理求出α1,α2,α3......αk,最小的p就为gcd(α1,α2,α3......αk)。有一个坑点:就是x可能为负数,如果x为负数的话,x = b^q, q必须使奇数,因为偶数的偶数次方大于正数,所以将x转化为正数求得的解如果是偶数的话必须将其一直除2转化为奇数。

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int book[1000002],tag[1000002],tt;
void su()
{
    book[1]=1;
    tt=0;
    for(int i=2; i<=1000000; i++)
        if(book[i]==0)
        {
            tag[tt++]=i;
            for(int j=i*2; j<=1000000; j=j+i)
                book[j]=1;
        }
}
int gcd(int x,int y)
{
    return y?gcd(y,x%y):x;
}
int main()
{
    su();
    int t,kk=1;
    scanf("%d",&t);
    while(t--)
    {
        long long n;
        int flag1=0;
        scanf("%lld",&n);
        if(n<0)
        {
            n=-n;
            flag1=1;
        }
        int a[12000],h=0,u=0;
        for(int i=0; tag[i]*tag[i]<=n&&i<tt; i++)
        {
            int flag=0;
            int sum=0;
            while(n%tag[i]==0)
            {
                flag=1;
                sum++;
                n/=tag[i];
            }
            if(flag==1)
            {
                if(u==0)
                    u=sum;
                else
                    u=gcd(u,sum);
            }
            if(n==1)
                break;
        }
        if(n>1)
            u=1;
        if(flag1==1)
            while(u%2==0)
                u=u/2;
        printf("Case %d: %d\n",kk++,u);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值