/**Time: 156 ms, 但是当我把求素因子拆出来的时候,居然600ms *题目大意: * 求二次剩余,求雅克比符号,然后根据性质把雅克比符号转换为勒让德符号。 * 注意判断勒让德符号的结果,可以用欧拉准则,L(a, n),当 n|a时,结果为0, * 否则用a^((n - 1) / 2) mod n来求。(欧拉函数的适用范围是当n为奇素数) *解题思路: * 直接用欧拉准则来模拟即可。不需要管题目的一大堆性质,注意提取题目有用的信息。 *题目困惑: * 当用J(a, n)中的n不是素数要装换为 J (a, n) = J (a, p1) *J (a, p2)…* J (a, pm), * p1…pm is the prime factor of n.的时候,2是偶数,但是此题还是可以用 * 欧拉准则来处理。
*(傻逼了我,题目中根本就不可能出现2,因为n是奇数,那么n的素因子是不可能出现2的。)
*/
View Code
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 5 const int MAX = 1000000 + 1; 6 int prime[MAX]; 7 bool isPrime[2 * MAX]; 8 /** 9 prim: 将素数压入此数组中,如2,3,5,7,11,13,17,19... 10 isPrime: 下表为i的数,是否为素数 11 n: 判断小于等于n的数,prime的上限 12 m: isPrime的上限(n <= m <= n*n) 13 14 返回:素数的个数 15 */ 16 int getPrime(int*prime, bool*isPrime, int n, int m) 17 { 18 int p,i,j; 19 memset(isPrime, 1, m); 20 p=isPrime[0]=isPrime[1]=0; 21 for(i=2;i<=n;i++) 22 if(isPrime[i]) 23 for(prime[p++]=i,j=2*i;j<=m;j+=i) 24 isPrime[j] = false; 25 return p; 26 } 27 28 //整数分解(>=2)(分解为质因子相乘) 29 //Prime做到√maxn就行了,isPrime做到maxn 30 int resolve(int x, int *arr) 31 { 32 int len = 0; 33 for(int i = 0; x != 1; i ++) 34 { 35 if(isPrime[x]) 36 { 37 arr[len ++] = x; 38 break; 39 } 40 while(x % prime[i] == 0) 41 { 42 arr[len ++] = prime[i]; 43 x /= prime[i]; 44 } 45 } 46 return len; 47 } 48 49 /** 50 返回(a^b)%w; 51 O(lg(b))的效率 52 */ 53 //注意中间结果是否会溢出 54 int mod_pow(__int64 a, __int64 k, __int64 m) 55 { 56 static __int64 r; 57 for(r=1; k; k>>=1, a=a*a%m) 58 if(k&1) r = r*a%m; 59 return (int)r; 60 } 61 62 int oula_judge(int a, int n) 63 { 64 if(a % n == 0) 65 return 0; 66 int t = (n - 1) / 2; 67 int temp = mod_pow(a, t, n); 68 if(temp == 1) 69 return 1; 70 else 71 return -1; 72 } 73 74 int main(void) 75 { 76 getPrime(prime, isPrime, 1000000, 2 * 1000000); 77 int a, n; 78 while(scanf("%d %d", &a, &n) == 2) 79 { 80 if(isPrime[n] == 1) 81 { 82 cout << oula_judge(a, n) << endl; 83 } 84 else 85 { 86 //cout << "conm,e" << endl; 87 int ans = 1; 88 //注释的这一段600ms 89 /*for(int i = 0; n != 1; i++) 90 { 91 int cnt = 0; 92 while(n % prime[i] == 0) 93 { 94 n /= prime[i]; 95 cnt++; 96 } 97 int t = oula_judge(a, prime[i]); 98 ans *= (int)pow((double)t, (double)cnt); 99 }*/ 100 int factor[100000]; 101 int len = resolve(n, factor); 102 for(int i = 0; i < len; i++) 103 { 104 ans *= oula_judge(a, factor[i]); 105 } 106 cout << ans << endl; 107 } 108 } 109 return 0; 110 }