唯一分解定理的应用 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

 

题意:题目给 X数是一个 32位的数;差不多在 1e10 左右·;我们求素数 只需要 到 1e6就足够了;

例如式子 X=b^ {p}  ;给你一个X 值;求瞒住式子的最大P为多少;例如144=6^2;我们就需要输出 2;

刚开始看到这道题,我想到的就是用唯一分解定理分解;然后 求 素数因子的幂次;最后就卡死了;

最后模拟了几个样例;找到了规律;就是找素数因子幂次(出现的次数)的最大公约数就好了;

例如144=2^4*3^2;  4和2的最大公约数就是 2; 所以 144=(2^2*3)^2=6^2; 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int maxx=1002000;
long long a[maxx];
long long b[maxx];
long long c[maxx];///存指数出现的次数
long long cnt,d;
void sh()
{
    cnt=0;
    for(int i=2; i<maxx; i++)
    {
        if(a[i]==0)
            b[cnt++]=i;
        for(int j=0; j<cnt&&b[j]*i<=maxx; j++)
        {
            a[i*b[j]]=1;
            if(i%b[j]==0)
                break;
        }
    }
}
void cal(long long n)
{
    memset(c,0,sizeof(c));
    d=0;
    for(long long i=0; i<cnt&&b[i]<=sqrt(n); i++)
    {
        if(n%b[i]==0)///标记素数因子
            d++;
        while(n%b[i]==0)
        {
            c[d]++;///计算相应素数因子出现的素数
            n/=b[i];
        }
    }
    if(n>1)
    {
        c[1]=1;
        d=1;
    }
}
int main()
{
    long long t,x,cas=0;
    cin>>t;
    sh();
    while(t--)
    {
        cin>>x;
        int f=0;
        if(x<0)
        {
            x=-x;
            f=1;
        }
        cal(x);
        long long cc=c[1];
        if(f)
        {
            for(int i=1; i<=d; i++)
            {
                while(c[i]%2==0)
                    c[i]/=2;
                cc=__gcd(cc,c[i]);
            }
        }
        else
        {
            for(int i=1; i<=d; i++)
                cc=__gcd(cc,c[i]);
        }
        printf("Case %lld: %lld\n",++cas,cc);
    }
    return 0;
}

对于唯一分解定理有跟多应用的大佬;可以留言;我去学习学习;谢谢!希望多多指教!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值