题目传送门
给定整数 $x$,使得 $x = a^p$,那么 $p$ 最大是多少?
多测,$x$ 在 int
范围内。
题解
根据唯一分解定理,一个数一定能够表示为 ${p_1}^{a_1} {p_2}^{a_2} \cdots {p_i}^{a_i}$,其中 $p_1, p_2, \cdots, p_i$ 均为质数。
那么题目中所求的最大的符合条件的 $p$ 一定是 $\gcd(a_1, a_2, \cdots , a_i)$。
所以我们可以在 $O(\sqrt{n})$ 的时间内求出一个数的分解式,对指数求 $\gcd$ 即可。
但是题目中没有对数字的正负做出限制,所以当输入的数字是负数时,求完 $\gcd$ 后要除掉所有的 $2$。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include <bits/stdc++.h> #define _rep(i, x, y) for(int i = x; i <= y; i++) #define LL long long using namespace std; template <typename T> inline void read(T &x) { x = 0; LL f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -1; for (; isdigit(c); c = getchar()) x = x * 10 + c - 48; x *= f; } template <typename T> inline void write(T x) { if(x < 0) {putchar('-'); x = -x;} if(x > 9) write(x / 10); putchar(x % 10 + '0'); } LL p; bool flg = false; int expo[65546];
int gcd(int x, int y) { return x%y == 0? y : gcd(y, x%y); }
int main() { while(scanf("%lld", &p) != EOF && p) { flg = false; if(p < 0) { p = -p; flg = true; } int k = 0; memset(expo, 0, sizeof(expo)); _rep(i, 2, sqrt(p)) { while(p % i == 0) { expo[i]++; p /= i; } if(expo[i]) { if(k == 0) k = expo[i]; else k = gcd(k, expo[i]); } }
if(p > 1) {k = 1;} if(flg) {while(k % 2 == 0) k /= 2; } printf("%d\n", k); } return 0; }
|