Jacobi symbol
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 514 Accepted Submission(s): 193
Problem Description
Consider a prime number p and an integer a !≡ 0 (mod p). Then a is called a quadratic residue mod p if there is an integer x such that x
2 ≡ a (mod p), and a quadratic non residue otherwise. Lagrange introduced the following notation, called the Legendre symbol, L (a,p):
For the calculation of these symbol there are the following rules, valid only for distinct odd prime numbers p, q and integers a, b not divisible by p:
The Jacobi symbol, J (a, n) ,is a generalization of the Legendre symbol ,L (a, p).It defines as :
1. J (a, n) is only defined when n is an odd.
2. J (0, n) = 0.
3. If n is a prime number, J (a, n) = L(a, n).
4. If n is not a prime number, J (a, n) = J (a, p1) *J (a, p2)…* J (a, pm), p1…pm is the prime factor of n.
For the calculation of these symbol there are the following rules, valid only for distinct odd prime numbers p, q and integers a, b not divisible by p:
The Jacobi symbol, J (a, n) ,is a generalization of the Legendre symbol ,L (a, p).It defines as :
1. J (a, n) is only defined when n is an odd.
2. J (0, n) = 0.
3. If n is a prime number, J (a, n) = L(a, n).
4. If n is not a prime number, J (a, n) = J (a, p1) *J (a, p2)…* J (a, pm), p1…pm is the prime factor of n.
Input
Two integer a and n, 2 < a< =10
6,2 < n < =10
6,n is an odd number.
Output
Output J (a,n)
Sample Input
3 5 3 9 3 13
Sample Output
-1 0 1
Author
alpc41
Source
题目分析:
欧拉准则可以用于判断这个数是否能够二次剩余,其中要筛取素数表,来求取质因数,暴力求解即可
欧拉准则可以用于判断这个数是否能够二次剩余,其中要筛取素数表,来求取质因数,暴力求解即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 1000007
using namespace std;
typedef long long LL;
int a,n;
int prime[MAX];
int vis[MAX];
int cnt;
void init ( )
{
for ( int i = 1 ; i < MAX ; i++ ) vis[i] = 1;
cnt = 0;
vis[1] = vis[0] = 0;
for ( LL i = 2 ; i < MAX ; i++ )
{
if ( !vis[i] ) continue;
vis[i] = cnt , prime[cnt++] = i;
for ( LL j = i*i ; j < MAX ; j+= i )
vis[j] = 0;
}
}
int factor[MAX];
int sum;
void pre ( int n )
{
sum = 0;
for ( int i = 0 ; i < cnt && prime[i] <= n ; i++ )
{
while ( !(n%prime[i]) )
{
factor[sum++] = prime[i];
n /= prime[i];
}
}
if ( n != 1 ) factor[sum++] = n;
}
int pow ( LL a , LL n , LL p )
{
if ( n == 0 ) return 1;
LL temp = pow ( a , n/2 , p )%p;
if ( n&1 ) return (int)(temp*temp%p*a%p);
else return (int)(temp*temp%p);
}
int euler_check ( int a , int n )
{
if ( a%n == 0 ) return 0;
int temp = pow ( a , (n-1)/2 , n );
if ( temp == 1 ) return 1;
else return -1;
}
int main ( )
{
init ( );
while ( ~scanf ( "%d%d" , &a , &n ) )
{
pre ( n );
int ans = 1;
for ( int i = 0 ; i < sum ; i++ )
ans *= euler_check ( a , factor[i] );
printf ( "%d\n" , ans );
}
}