LightOJ - 1220唯一分解定理+GCD思想

第100Blog纪念

1220 - Mysterious Bacteria
Time Limit: 0.5 second(s)Memory Limit: 32 MB

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 pnew 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

Output for Sample Input

3

17

1073741824

25

Case 1: 1

Case 2: 30

Case 3: 2

 题意很简单 给你 X ,问你 满足 X  == b ^ p时, p的最大值是多少,b可以为任何值.

注意! n可以为负数,被这里卡了很久....

题解 通过将x唯一分解得到

    x = a1^p1 * a2^p2 * a3^p3***an^pn

于是这个时候我们将p的最大值就是gcd(p1,p2,...,pn)

因为gcd(p1,p2,p3,...,pn)是他们的最大公约数,只有其才能整除所有pi,即构成pth数

但是这里有个坑点,以上对与n为正数时是满足.

但是n为负数时,需要先把n取绝对值再算.但是你以为就这么简单吗

比如 -4 ,你将其转化为正数再算时,得到的解是2 ,   (-2)^2 = 4 显然p=2是错的

当n是负数时,则p的值一定是奇数,因为一个数的偶数次方一定为正数,因此需要将它的素因子个数全都化为奇数

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
bool isprime[maxn];
vector<int> primes;
int e[maxn],divs[maxn];
int gcd(int a,int b) { return b == 0 ? a : gcd(b,a%b);}
void creatprime()
{
    memset(isprime,true,sizeof(isprime));
    primes.clear();
    isprime[0] = isprime[1] = 0;
    for(int i=2;i<maxn;i++) {
        if(isprime[i]) primes.push_back(i);
        for(int j=0;j<primes.size() && i*primes[j]<maxn;j++) {
            isprime[i*primes[j]] = 0;
            if(i % primes[j] == 0) break;
        }
    }
}
int solve(ll n) {
    memset(e,0,sizeof(e));
    int cnt = 0;
    for(int i=0;i<primes.size() && primes[i]*primes[i]<=n;i++) {
        if( n % primes[i] == 0) {
            int num = 0;
            divs[++cnt] = primes[i];
            while(n % primes[i] == 0) n/=primes[i],e[cnt]++;
        }
    }
    if(n > 1) divs[++cnt] = n,e[cnt]++;
    if(cnt == 1) return e[1];
    int ans = e[1];
    for(int i=2;i<=cnt;i++) ans = gcd(ans,e[i]);
    return ans;
}
int main()
{
    creatprime();
    int caset,cas=0;scanf("%d",&caset);
    ll n;
    while(caset--) {
        bool flag = false;
        scanf("%lld",&n);
        if(n < 0) n = -n,flag = true;
        int ans = solve(n);
        if(flag) while(ans % 2==0) ans /= 2;
        printf("Case %d: %d\n",++cas,ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值