第100Blog纪念
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;
}