2021SC@SDUSC
jacobi符号
数学原理:中国剩余定理,同余式,二次同余式,勒让德符号
中国剩余定理
//中国剩余定理模板代码
typedef long long ll;
ll china(ll a[],ll b[],int n)//a[]为除数,b[]为余数
{
ll M=1,y,x=0;
for(int i=0;i<n;++i) //算出它们累乘的结果
M*=a[i];
for(int i=0;i<n;++i)
{
ll w=M/a[i];
ll tx=0;
int t=exgcd(w,a[i],tx,y); //计算逆元
x=(x+w*(b[i]/t)*x)%M;
}
return (x+M)%M;
}
同余式
定义3.11设m是一个正整数.设f(x)=anx^n+…+a1^x+a为多项式,其中a是整数,则f(x)≡0(modm)叫做模m同余式.若an≠0(modm),则n叫做f(x)的次数,记为degf.此时,(2)式又叫做模m的n次同余式如果整数x=a使得(2)成立,
即f(a)≡0(modm),则a叫做该同余式(2)的解。
事实上,满足x≡a(modm)的所有整数都使得同余式(2)成立,即a所在剩余类
C a = {c | c ∈ Z, c ≡ a (mod m)}
中的每个剩余都使得同余式(2)成立,因此,同余式(2)的解a通常写成(mod m)在模m的完全剩余系中,使得同余式(2)成立的剩余个数叫做同余式(2)的解数
二次同余式
求解形如 x^2 = a (mod p) 这样的同余式
代码:
/*
模P平方根:
求 X ^2 = a (mod p)
定理:当P为奇素数的时候
先判断(a / p )的勒让德符号, 若为-1则无解,若为1则有解
分解P-1,然后求B,然后求出X(t-1),和a的逆元
然后开始求 ans = ( a的逆元 * 上一个X的平方(t-k))的(t-k-1)次方对P取模
如果 ans == -1 则 J = 1;
如果 ans == 1 则 J = 0;
然后开始求现在的 X = (上一个X * B的(J*2的k次方)次方
直到求出X0,也就是最后的解
*/
#include<bits/stdc++.h>
using namespace std;
void Divide(int p, int &t, int &s)
{
t = 0, s= 0;
while(p % 2 == 0)
{
t++;
p /= 2;
}
s = p;
return ;
}
int Pow(int a, int b, int mod)
{
int ans = 1, base = a;
while(b != 0)
{
if(b & 1)
ans = (ans * base) % mod;
base = (base * base) % mod;
b >>= 1;
}
return ans;
}
int Legendre(int a, int p)
{
if(a == 2)
{
int x = (p+1)*(p-1)/8;
if(x % 2 == 0)
return 1;
else
return -1;
}
else
{
int ans = Pow(a, (p-1)/2, p);
if(ans == p-1)
return -1;
else
return 1;
}
}
具体代码见@元解~殇怀
勒让德符号
勒让德符号可以计算当p为素数的情况的二次剩余判别问题,而雅可比符号判定条件为a为任意整数,p为任意奇数。
高斯推导出著名的二次互反律。
通过二次互反律解决了勒让德符号的计算问题,可以通过递归调用解决计算。
int Legrend(int a, int p)
{if (a == 1)
return1;
if (p % a== 0)
return0;
if (a % 2== 0)
returnLegrend(a / 2, p) * pow(-1, (pow(p, 2) - 1) / 8);
return Legrend(p%a, a)*pow(-1, (a - 1)*(p - 1) / 4);}