HDU3589-雅可比符號
題意
給出a,n滿足n是奇數,$1<a,n\leqslant 1000000$,求雅可比符號$\left(\frac{a}{n}\right)$
分析
可以拿定義硬上,因子分解然後用勒讓德符號
勒讓德符號的歐拉判別法:設p是奇素數,a是不被p整除的正整數,則
$\left(\frac{a}{n}\right)=a^{\frac{n-1}{2}} (mod\,p)$
雅可比符號是勒讓德符號的推廣
設n是正奇數,其素冪因子分解式為$n={p_1}^{t_1}{p_2}^{t_2}\cdots{p_m}^{t_m}$
令a是與n互素的正整數,則雅可比符號定義是
$\left(\frac{a}{n}\right)=\prod\limits_{i=0}^{m}\left(\frac{a}{p_i}\right)^{t_i}$
其中等式的右邊是勒讓德符號
這裏給出另外一種方法,類比於歐幾裏得算法
設a和b是正整數,令$R_0=a,R_1=b$,利用帶余除法,並提取出余數中2的最高次冪得
$R_0=R_1q_1+2^{s_1}R_2$
其中$s_1$是非負整數,$R_2$是小於$R_1$的正奇數
反復使用帶余除法,並提取出余數中的2的最高次冪得
$R_1=R_2q_2+2^{s_2}R_3$
$R_2=R_3q_3+2^{s_3}R_4$
$\cdots$
$R_{n-3}=R_{n-2}q_{n-2}+2^{s_{n-2}}R_{n-1}$
$R_{n-2}=R_{n-1}q_{n-1}+2^{s_{n-1}}\cdot 1$
計算雅可比符號的定理:
$\left(\frac{a}{b}\right)=(-1)^{\sum\limits_{i=1}^{n-1}(s_1\frac{{R_i}^2-1}{8}+\frac{(R_i-1)(R_{i+1}-1)}{4})}$
代碼
#include <cstdio> #include <cstring> using namespace std; int r[100],s[100]; int gcd(int a,int b){return b==0?a:gcd(b,a%b);} int jcb(int a,int b){ if(gcd(a,b)>1)return 0; r[0]=a;r[1]=b; memset(s,0,sizeof s); int n=1; while(r[n++]!=1){ r[n]=r[n-2]%r[n-1]; while(r[n]&1^1)r[n]>>=1,s[n-1]++; } int p=0; for(int i=1;i<n;i++)r[i]&=7,s[i]&=1; for(int i=1;i<n;i++){ p^=(s[i]*((r[i]*r[i])-1)/8)&1; p^=((r[i]-1)*(r[i+1]-1)/4)&1; } return 1-2*p; } int main(){ int a,n; while(~scanf("%d%d",&a,&n)){ printf("%d\n",jcb(a,n)); } return 0; }
HDU3589-雅可比符號