LightOJ 1220 Mysterious Bacteria(唯一分解定理 + 素数筛选)
http://lightoj.com/volume_showproblem.php?problem=1220
Description
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 = b^p,求p的最大值
x = p1^x1*p2^x2*p3^x3*...*ps^xs
开始我以为是找x1、x2、... 、xs中的最大值,后来发现想错了,x = b^p, x只有一个因子的p次幂构成
如果x = 12 = 2^2*3^1,要让x = b^p,及12应该是12 = 12^1
所以p = gcd(x1, x2, x3, ... , xs);
比如:24 = 2^3*3^1,p应该是gcd(3, 1) = 1,即24 = 24^1
324 = 3^4*2^2,p应该是gcd(4, 2) = 2,即324 = 18^2
本题有一个坑,就是x可能为负数,如果x为负数的话,x = b^q, q必须使奇数,所以将x转化为正数求得的解如果是偶数的话必须将其一直除2转化为奇数
#include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; const int N = 1e5 +10; const int INF = 0x3f3f3f3f; typedef long long ll; int prime[N], k; bool Isprime[N]; void Prime() { k = 0; memset(Isprime, true, sizeof(Isprime)); prime[1] = false; for(int i = 2 ; i < N ; i++) { if(Isprime[i]) { prime[k++] = i; for(int j = i ; 1LL * i * j < N ; j++) Isprime[i * j] = false; } } } int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } int main() { int t, p = 0; ll n;//n要用long long 定义,如果n是负数的话会超时 Prime(); scanf("%d", &t); while(t--) { p++; scanf("%lld", &n); int f = 0; if(n < 0) { n = - n;//int定义n这儿会卡住半天出不来,就会超时,为什么这样我也不知道 f = 1; } int x, ans = 0; for(int i = 0 ; i < k && prime[i] * prime[i] <= n ; i++) { if(n % prime[i] == 0) { x = 0; while(n % prime[i] == 0) { x++; n /= prime[i]; } if(ans == 0) ans = x; else ans = gcd(ans, x); } } if(n > 1) ans = gcd(ans, 1); if(f == 1) { if(ans % 2 == 0) ans = 1; } printf("Case %d: %d\n", p, ans); } return 0; }
/*
8 2147483647 -2147483648 32 -32 64 -64 4 -4 Output: Case 1: 1 Case 2: 31 Case 3: 5 Case 4: 5 Case 5: 6 Case 6: 3 Case 7: 2 Case 8: 1
*/