/*题意:给出一个数,注意有可能是负数,这个数能表示为x=b^p,求最大的p 解题:这道题比较卡精度,所以直接用__int64,负数的话就输入后处理一下,用Pollard分解一下这个数,获得这个数得标准分解式, 即这个数的素数乘积表达式,问题就是求组成这个数的这些素数的幂数的最大公约数,注意负数的答案只能是奇数,若得到的答案是偶数, 需要不断除以2直至获得一个奇数答案为止。 16msACc++代码*/ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include<algorithm> using namespace std; typedef __int64 int_type; map<int_type,int_type> mm; int_type Montgomery(int_type n,int_type p,int_type m) { //蒙哥马利法快速计算(n^p)%m的值 int_type k = 1; n%=m; while(p!=1) { if(0!=(p&1))k=(k*n)%m; n=(n*n)%m; p>>=1; } return(n*k)%m; } bool Miller_rabin(int_type n, int timenum = 10) { if (n < 2) return false; if (n == 2) return true; while (timenum--) { if ( Montgomery(rand() % (n - 2) + 2, n - 1, n) != 1) return false; } return true; } void Pollard(int_type n); int_type factor[10000],cnt; int_type Gcd(int_type a, int_type b) { int_type temp; if (b > a) { temp = a; a = b; b = temp; } while (b != 0) { temp = a % b; a = b; b = temp; } return a; } int_type Mul_Mod(int_type a, int_type b, int_type c) //求(a*b)%c { if (b == 0) return 0; int_type ans = Mul_Mod(a, b / 2, c); ans = (ans * 2) % c; if (b % 2) ans = (ans + a) % c; return ans; } void Factor(int_type n) { int_type d = 2; while (true) { if (n % d == 0) { Pollard(d); Pollard(n / d); return; } d++; printf("%I64d**\n",d); } } void Pollard(int_type n) { if (n <= 0) printf("error\n"); if (n == 1) return; if (Miller_rabin(n)) { if(mm[n] == 0) { factor[cnt++] = n; mm[n]++; } else mm[n]++; return; } int_type i = 0, k = 2, x, y, d; x = y = rand() % (n - 1) + 1; while (true) { i++; x = (Mul_Mod(x, x, n) + n - 1) % n; d = Gcd((y - x + n) % n, n); if (d != 1) { Pollard(d); Pollard(n / d); return; } if (i == k) { y = x; k *= 2; } } Factor(n); } int main() { int_type k,i,j; bool ff; while(scanf("%I64d",&k),k) { ff = 0; if(k < 0) { k = 0 - k; ff = 1; } if(!Miller_rabin(k)) { mm.clear(); cnt = 0; Pollard(k); j = mm[factor[0]]; for(i = 1; i < cnt; i++) { j = Gcd(j,mm[factor[i]]); } if(ff == 0) { printf("%I64d\n",j); } else { while(j%2 == 0) j = j/2; printf("%I64d\n",j); } } else { printf("1\n"); } } return 0; }