数论(分解质因数) - Mysterious Bacteria - LightOJ 1220

数论(分解质因数) - Mysterious Bacteria - LightOJ 1220

题意:

x p 使 a p = x , ( a ) 给定正整数x,求满足条件的最大的指数p,使得a^p = x,(a是整数)。

Input

输入包含多组样例T(T≤50),每个样例包括一个整数x,x的范围在32位二进制数以内, 保证x的绝对值大于等于2。

Output

对于每个样例输出最大的指数p。

Sample Input

3
17
1073741824
25

Sample Output

Case 1: 1
Case 2: 30
Case 3: 2

T i m e   l i m i t 500 m s M e m o r y   l i m i t 32768 k B Time \ limit:500 ms,Memory\ limit:32768 kB


分析:

x x = p 1 a 1 × p 2 a 2 × . . . × p k a k 已知,对任意正整数x,可分解为x=p_1^{a_1}×p_2^{a_2}× ...×p_k^{a_k}

x = a p p a 1 , a 2 , . . . , a k 使 p g c d ( a 1 , a 2 , . . . , a k ) 转化为x=a^p,则p为a_1,a_2,...,a_k的一个公约数,要使得p最大,即求gcd(a_1,a_2,...,a_k)。

注意:

x x可能是负数,我们可取其绝对值进行因式分解。

x p p 2 p 但是当x是负数时,p必然是奇数。若求得的p是偶数,我们要不断除2,直到p是奇数。

x = 2147483648 x 2147483648 当x=-2147483648时,-x仍然是-2147483648。

2147483648 x 对负数开根号的结果仍然是-2147483648,这就可能导致不对x进行质因数分解,可能会造成死循环。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>

#define ll long long

using namespace std;

const int N=1e5+10;

int primes[N],cnt;
bool st[N];

void get_prime(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]*i<=n;j++)
        {
            st[primes[j]*i]=true;
            if(i%primes[j]==0) break;
        }
    }
}

int gcd(int a,int b)
{
    return b ? gcd(b,a%b) : a;
}

int solve(ll x)
{
    ll tmp=x;
    if(x<0) x=-x;
    int res=0;
    
    int sqx=sqrt(x);
    for(int i=0;i<cnt && primes[i]<=sqx;i++)
    {
        int p=primes[i];
        if(x%p==0)
        {
            int cnt=0;
            while(x%p==0)
            {
                x/=p;
                cnt++;
            }
            res=gcd(cnt,res);
        }
    }
    
    if(x>1) res=1;
    if(tmp<0)
        while(res%2==0) res/=2;
    return res;
}

int main()
{
    get_prime(N-1);
    
    int T; cin>>T;
    for(int t=1;t<=T;t++)
    {
        ll x; cin>>x;
        printf("Case %d: %d\n",t,solve(x));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/njuptACMcxk/article/details/107771188