LightOJ-1220 Mysterious Bacteria (素数打表+欧几里得算法+唯一分解定理)给出x,求x=a^p,最大的指数

题目大意:

x = b^p, x只有一个因子的p次幂构成
如果24 = 2^3*3^1,p应该是gcd(3, 1) = 1,即24 = 24^1
324 = 3^4*2^2=(3^2*2)^2,p应该是gcd(4, 2) = 2,即324 = 18^2
所以p = gcd(x1, x2, x3, ... , xn){欧几里得算法求取最大公约数};
*本题有一个坑,就是x可能为负数,如果x为负数的话,x = b^q, q必须使奇数,所以将x转化为正数求得的解如果是偶数的话必须将其一直除2转化为奇数

题目:

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 xdays. 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

AC代码:

#include<iostream>
#include<string.h>
typedef long long ll;
#include<stdio.h>
using namespace std;
#define M 1000010
int dp[M];
int book[M];
int t,k;
ll m;
void dfs()
{
    k=0;
    memset(dp,0,sizeof(dp));
    memset(book,0,sizeof(book));
    for(int i=2; i<M; i++)/**因为任何一个整数都可以由一个素数经过乘法运算得到,故可通过素数打表的方式求得某数的唯一分解(得到幂次最大)*/
        if(!book[i])
        {
            dp[k++]=i;/*记录素数*/
            for(int j=2; i*j<M; j++)
                book[j*i]=1;
        }
}
int gcd(int a,int b)
{
    return !b?a:gcd(b,a%b);
}
int main()
{
    cin>>t;
    int tt=1;
    dfs();
    while(t--)
    {
        int flag=0;
        cin>>m;
        if(m<0)/**本题的坑:m可能为负数*/
        {
            flag=1;
            m=-m;
        }
        int ans=0;
        for(int i=0;i<k&&dp[i]*dp[i]<=m;i++)/**care:remember停止条件为i<k&&dp[i]*dp[i]<=m,缺一不可*/
        {
            if(m%dp[i]==0)
            {
                int a=0;
                while(m%dp[i]==0)
                {
                    m/=dp[i];/**唯一分解定理:直接对m的值进行操作,得到x=a1^b1*a2^b2.....an^bn*/
                    a++;
                }
                if(ans=0)
                    ans=a;
                else
                    ans=gcd(ans,a);/**欧几里得算法:求得到的素数的幂次进行求取最大公约数操作*/
            }
            if(m==1)
                break;
        }
        if(m>1)/**则m为素数,因数只有1和自身*/
            ans=1;
        if(flag)/**填坑:若为负数,幂次不可能为偶数,故由最大公约数求出最大的奇数*/
        {
            while(ans%2==0)
                ans/=2;
        }
        printf("Case %d: %d\n",tt++,ans);
    }
    return 0;
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值