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 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.
输出
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 求 最大
p,x=ap
p
,
x
=
a
p
由唯一分解定理 我们可以得到
x=p1e1∗p2e2∗p3e3....pkek
x
=
p
1
e
1
∗
p
2
e
2
∗
p
3
e
3
.
.
.
.
p
k
e
k
同理
a=p1r1∗p2r2∗p3r3....pkek
a
=
p
1
r
1
∗
p
2
r
2
∗
p
3
r
3
.
.
.
.
p
k
e
k
那么 我们可以知道
p∗r1=e1...
p
∗
r
1
=
e
1
.
.
.
令
d=gcd(e1,e2,...ek)
d
=
g
c
d
(
e
1
,
e
2
,
.
.
.
e
k
)
可以求得最大p|d存在时p=d
可
以
求
得
最
大
p
|
d
存
在
时
p
=
d
注意x负数的情况 p必定为奇数
AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
#define LL long long
#define CLR(a,b) memset(a,(b),sizeof(a))
#define ls st<<1
#define rs st<<1|1
const int MAXN = 1e6+10;
int prime[MAXN];
int arr[MAXN];
bool is_prime(int x) {
if(x==2 || x==3)
return true;
if(x%2==0 || x%3==0 || x==1)
return false;
int k = sqrt(x)+1;
for(int i = 5; i <= k; i++) {
if(x%i==0 || x%(i+2)==0)
return false;
}
return true;
}
void getPrime()
{
memset(prime, 0, sizeof(prime));
for (int i = 2; i <= MAXN; i++)
{
if (!prime[i])
{
prime[++prime[0]] = i;
}
for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++)
{
prime[prime[j] * i] = 1;
if (i % prime[j] == 0)
{
break;
}
}
}
}
int gcd(int a, int b) {
if(b == 0) return a;
return gcd(b,a%b);
}
int main() {
getPrime();
int T;
cin >> T;
int k = 0;
while(T--) {
CLR(arr,0);
LL n;
cin >> n;
bool flag = true;
if(n < 0) {
flag = false;
n = -n;
}
int x = 0;
if(is_prime(n)) {
printf("Case %d: 1\n",++k); continue;
}
for(int i = 1; i < prime[0] && prime[i]*prime[i] <= n; i++) {
if(n%prime[i]==0) {
int kk = 0;
while(n%prime[i]==0) {
n /= prime[i];
kk++;
}
arr[x++] = kk;
}
}
int xx = arr[0];
//cout << arr[0] << " " << arr[1] << endl;
for(int i = 1; i < x; i++) {
xx = gcd(xx, arr[i]);
}
if(flag) {
printf("Case %d: %d\n",++k,xx);
}
else {
while(xx%2 == 0) {
xx /= 2;
}
printf("Case %d: %d\n",++k,xx);
}
}
return 0;
}