Jacobi symbolTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 549 Accepted Submission(s): 207
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.
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
Sample Output
Author
alpc41
Source
Recommend
|
题意:
求J(a,n)
解题思路:
二次剩余,欧拉准则!
在数论中,特别在同余理论裏,一个整数
对另一个整数
的二次剩余(英语:Quadratic residue)指
的平方
除以
得到的余数。
当对于某个
及某个
,式子
成立时,称“
是模
的二次剩余”
当对于某个
及某个
,
不成立时,称“
是模
的二次非剩余”
欧拉准则:
若
是奇质数且
不能整除
,则:
是模
的二次剩余 当且仅当:
![]()
是模
的非二次剩余当且仅当:
![]()
以勒让德符号表示,即为:
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN = 1000000+10;
typedef long long LL;
bool is_prime[MAXN];
int prime[MAXN];
void init()
{
int tot=0;
is_prime[0]=is_prime[1]=true;
for(int i=2;i<MAXN;i++){
if(!is_prime[i]){
prime[tot++]=i;
for(int j=i+i;j<MAXN;j+=i){
is_prime[j]=true;
}
}
}
}
int fast_power(int a,int n,int M)
{
LL res=1;
LL x=a;
while(n){
if(n&1) res=res*x%M;
x=x*x%M;
n>>=1;
}
return res%M;
}
int solve(int a,int p)
{
if(a%p==0) return 0;
return fast_power(a,(p-1)/2,p)==1?1:-1;
}
int main ()
{
int a,n;
init();
while(scanf("%d%d",&a,&n)!=EOF){
int ans=1;
if(is_prime[n]){
for(int i=0;prime[i]<=n;i++){
if(n%prime[i]) continue;
int cnt=0;
while(n%prime[i]==0){
n/=prime[i];
cnt++;
}
int t=solve(a,prime[i]);
if(t==-1&&cnt%2==0) t=1;
ans*=t;
}
}
else ans=solve(a,n);
printf("%d\n",ans);
}
return 0;
}