数论(分解质因数) - Mysterious Bacteria - LightOJ 1220
题意:
给 定 正 整 数 x , 求 满 足 条 件 的 最 大 的 指 数 p , 使 得 a p = x , ( a 是 整 数 ) 。 给定正整数x,求满足条件的最大的指数p,使得a^p = x,(a是整数)。 给定正整数x,求满足条件的最大的指数p,使得ap=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 Time limit:500ms,Memory limit:32768kB
分析:
已 知 , 对 任 意 正 整 数 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,可分解为x=p1a1×p2a2×...×pkak
转 化 为 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=ap,则p为a1,a2,...,ak的一个公约数,要使得p最大,即求gcd(a1,a2,...,ak)。
注意:
x 可 能 是 负 数 , 我 们 可 取 其 绝 对 值 进 行 因 式 分 解 。 x可能是负数,我们可取其绝对值进行因式分解。 x可能是负数,我们可取其绝对值进行因式分解。
但 是 当 x 是 负 数 时 , p 必 然 是 奇 数 。 若 求 得 的 p 是 偶 数 , 我 们 要 不 断 除 2 , 直 到 p 是 奇 数 。 但是当x是负数时,p必然是奇数。若求得的p是偶数,我们要不断除2,直到p是奇数。 但是当x是负数时,p必然是奇数。若求得的p是偶数,我们要不断除2,直到p是奇数。
当 x = − 2147483648 时 , − x 仍 然 是 − 2147483648 。 当x=-2147483648时,-x仍然是-2147483648。 当x=−2147483648时,−x仍然是−2147483648。
对 负 数 开 根 号 的 结 果 仍 然 是 − 2147483648 , 这 就 可 能 导 致 不 对 x 进 行 质 因 数 分 解 , 可 能 会 造 成 死 循 环 。 对负数开根号的结果仍然是-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;
}