【學習筆記】Pell方程

說明:
文中的分數 pq\frac{p}{q} 不一定滿足 gcd(p,q)=1\gcd(p,q)=1 ,也未必 p,qZp,q\in\Z
由於結論是需要證明的,所以結論用 \therefore 作開頭,以強調。

1.概述

有關 x,yx,y 的方程 x2ny2=1(nZ,n0)x^2-ny^2=1\quad(n\in\Z,n\ne 0)

被稱爲 PellPell 方程。我們要處理的是 x,yx,y 的正整數解。

不難發現,n<0n<0 時,無正整數解;在 n=0n=0 時,額……;在 n>0n>0nZ\sqrt{n}\in\Z 時,令 t=ynN+t=y\sqrt{n}\in\N^+ ,方程轉化爲 x2t2=1x^2-t^2=1 ,無正整數解。

所以,我們實際上考慮的是

x2ny2=1(x,y,nN+,n∉Z)\therefore x^2-ny^2=1\quad(x,y,n\in\N^+,\sqrt{n}\not\in\Z)

2.連分數

推薦刊物:數學吧之連分數,蠻不錯的。

1.定義

我們僅研究簡單連分數 a0+1a1+1a2+1a3+a_0+\frac{1}{a_1+\frac{1}{a_2+\frac{1}{a_3+\cdots}}}

可能是有限的,也可能是無限的。用一種更簡單的形式表達,可寫成

[a0;a1,a2,][a_0;a_1,a_2,\dots]

倘若有限,一般會給出項數 [a0;a1,a2,,ak][a_0;a_1,a_2,\dots,a_k]

2.計算

顯然我們有 [a0;a1,a2,,ak]=a0+1[a1;a2,a3,,ak][a_0;a_1,a_2,\dots,a_k]=a_0+\frac{1}{[a_1;a_2,a_3,\dots,a_k]}

也可能是無限連分數。但是,倘若 [a1;a2,a3,,ak]=pq[a_1;a_2,a_3,\dots,a_k]=\frac{p}{q}

(或者所謂的 limk+[a1;a2,a3,,ak]=pq\lim_{k\rightarrow+\infty}[a_1;a_2,a_3,\dots,a_k]=\frac{p}{q} ),那麼我們有

[a0;a1,a2,,ak]=q+a0pp\therefore [a_0;a_1,a_2,\dots,a_k]=\frac{q+a_0p}{p}

3.漸進分數

1.定義

定義一個連分數 aakk 階漸進分數 pkqk=[a0;a1,a2,,ak]\frac{p_k}{q_k}=[a_0;a_1,a_2,\dots,a_k]

注意,原連分數的長度可能是任意一個不小於 kk 的值,或者是無限連分數。

2.性質

對於任意 k(k2)k(k\ge 2) ,我們有

{pk=akpk1+pk2qk=akqk1+qk2\therefore\begin{cases} p_k=a_kp_{k-1}+p_{k-2}\\ q_k=a_kq_{k-1}+q_{k-2} \end{cases}

該定理可以使用數學歸納法證明。在 k=2k=2 時不難驗證;對於 k(k>2)k(k>2) 的情況,記連分數 a=[a1;a2,a3,,ak]a'=[a_1;a_2,a_3,\dots,a_k] 的漸進分數爲 pq\frac{p'}{q'} ,由歸納法有

{pk=akpk1+pk2qk=akqk1+qk2\begin{cases} p'_k=a_kp'_{k-1}+p'_{k-2}\\ q'_k=a_kq'_{k-1}+q'_{k-2} \end{cases}

2.3 告訴我們

{pk=a0pk+qkqk=pk\begin{cases} p_k=a_0p'_k+q'_k\\ q_k=p'_k \end{cases}

將角標換成 k1k-1k2k-2 自然也成立。進一步推導有

pk=a0(akpk1+pk2)+(akqk1+qk2)=ak(a0pk1+qk1)+(a0pk2+qk2)=akpk1+pk2\begin{aligned} p_k&=a_0(a_kp'_{k-1}+p'_{k-2})+(a_kq'_{k-1}+q'_{k-2})\\ &=a_k(a_0p'_{k-1}+q'_{k-1})+(a_0p'_{k-2}+q'_{k-2})\\ &=a_kp_{k-1}+p_{k-2} \end{aligned}

qq 便不展開了,可自證,無任何難度。

3.新的約定

我們規定

{p1=1q1=0,{p2=0q2=1\begin{cases} p_{-1}=1\\ q_{-1}=0 \end{cases} , \begin{cases} p_{-2}=0\\ q_{-2}=1 \end{cases}

這會使得 2.3.2 對於任意 kNk\in\N 都成立。

4.重要結論

2.3.2 中的公式,上式乘 qk1q_{k-1} 得到

pkqk1=akpk1qk1+pk2qk1(1)p_kq_{k-1}=a_kp_{k-1}q_{k-1}+p_{k-2}q_{k-1}\tag{1}

下式乘 pk1p_{k-1} 得到

qkpk1=akqk1pk1+qk2pk1(2)q_kp_{k-1}=a_kq_{k-1}p_{k-1}+q_{k-2}p_{k-1}\tag{2}

(2)(2)(1)-(1) 式得到

qkpk1pkqk1=(qk1pk2pk1qk2)q_kp_{k-1}-p_kq_{k-1}=-(q_{k-1}p_{k-2}-p_{k-1}q_{k-2})

左右兩邊的形式是相仿的,我們可以定義新數列 {qnpn1pnqn1}\{q_{n}p_{n-1}-p_{n}q_{n-1}\} ,結合首項 q0p1p0q1=1q_0p_{-1}-p_{0}q_{-1}=1 推出

qkpk1pkqk1=(1)k\therefore q_{k}p_{k-1}-p_kq_{k-1}=(-1)^k

4.逼近無理數

楊中和《二次無理數的連分數》講的非常清楚,嚴謹。果然還是要看專業文獻。

設我們正在展開 n+bc\frac{\sqrt{n}+b}{c} ,滿足 bZ,cN+b\in\Z,c\in\N^+ 。不妨設其值爲 a+1ra+\frac{1}{r} ,其中 aZa\in\Z ,而 rr 是另一個連分數。由於 r(1,+)    1r(0,1)r\in(1,+\infty)\;\Leftrightarrow\;\frac{1}{r}\in(0,1) ,我們要取最大的 aa ,具體方案是

maximize  bn,s.t.  c(b+b)\text{maximize}\;b'\le\sqrt{n},\text{s.t.}\;c|(b+b')

然後我們就有

a=b+bc  r=n+b(nbb)/c a=\frac{b+b'}{c}\\ \;\\ r=\frac{\sqrt{n}+b'}{(n-b'\cdot b')/c}

rr 是化簡後的結果。分母有理化就不在這裏進行了。下證 nbbcN+\frac{n-b'\cdot b'}{c}\in\N^+

  • 注意到 bb(modc)b'\equiv -b\pmod{c} ,故 nbbnb2(modc)n-b'\cdot b'\equiv n-b^2\pmod{c} 。該值爲正是顯然的,因爲 bnb'\le\sqrt{n}
  • 利用數學歸納法,b=0c=1b=0\wedge c=1 時顯然成立。設 c=(nbb)/cc'=(n-b'\cdot b')/c ,則 (nbb)/c=cZ(n-b'\cdot b')/c '=c\in\Z ,故得證。

那麼,這個連分數有多長呢?答案是,一定會出現循環。不難發現,如果 n+bc\frac{\sqrt{n}+b}{c} 在之前出現過,那麼就循環了。我們的算法中,bnb\le\sqrt{n} ,而且該值 >1>1 ,推出 2nn+b>c2\sqrt{n}\ge\sqrt{n}+b>c 。不同形式有限,鴿籠原理,必定有循環。

爲了讓整個過程更直觀,令 k=nk=\lfloor\sqrt{n}\rfloor ,再令 nx=nx2n_x=n-x^2 ,我們有

n=[k;k+i1nk,i1+i2ni1/nk,,j1+ip,i+j2ni/p,]\sqrt{n}=\left[k;\frac{k+i_1}{n_k},\frac{i_1+i_2}{n_{i_1}/n_k},\cdots,\frac{j_1+i}{p},\frac{i+j_2}{n_i/p},\cdots\right]

現在我們來揭示這個連分數的一些規律,以其中的任意兩項 j1+ip,i+j2ni/p\frac{j_1+i}{p},\frac{i+j_2}{n_i/p} 作代表。

  • 兩個相鄰的分母,乘積爲共有的分子的過渡數 nin_i

另外一個比較重要的結論是:

  • 由於該比值爲正整數,所以 pj1+ik+ip\le j_1+i\le k+i ,也有 ni/pi+j2k+in_i/p\le i+j_2\le k+i
  • 由於 ii 充分大,所以 p>kip>k-i ,否則 ii 可以再增大 pp
  • 注意到 ni>k2i2=(ki)(k+i)n_i>k^2-i^2=(k-i)(k+i) ,故 nip>(ki)(k+i)k+i=ki\frac{n_i}{p}>\frac{(k-i)(k+i)}{k+i}=k-i
  • 綜上:p,nip(ki,k+i]p,\frac{n_i}{p}\in(k-i,k+i] 。換言之,兩個相鄰分母在 kk 的鄰域裏,半徑爲共有因子。

然後我們可以證明,循環節從第二個開始。使用反證法。假設循環從 ll 始,由 rr 終。

n=[,b+blc,bl+bl+1cl,,br+blcr,bl+bl+1cl,]\sqrt{n}=\left[\dots,\frac{b'+b_l}{c'},\frac{b_l+b_{l+1}}{c_l},\dots,\frac{b_r+b_l}{c_r},\frac{b_l+b_{l+1}}{c_l},\dots\right]

由之前的結論,ccl=nbl2c'\cdot c_l=n-b_l^2crcl=n2bl2c_r\cdot c_l=n^2-b_l^2 ,所以 c=crc'=c_r

用上 c=crc'=c_r 的結論,由於 b+blc\frac{b'+b_l}{c'}br+blcr\frac{b_r+b_l}{c_r} 都是整數,所以 bbr(modc)b'\equiv b_r\pmod{c'}

之前證明過了 kbr<ck-b_r<c'kb<ck-b'<c' 。在 b=br+cb'=b_r+c' (或者更大)時,b>(kc)+c=kb'>(k-c')+c'=k ,矛盾;在 b=brcb'=b_r-c' (或者更小)時,c>k(brc)    kbr<0c'>k-(b_r-c')\;\Leftrightarrow\;k-b_r<0 不可能成立。

所以我們有了重要結論 {b=brc=cr\begin{cases}b'=b_r\\c'=c_r\end{cases}

所以循環可以從 b,cb',c' 開始,到 br1,cr1b_{r-1},c_{r-1} 結束——循環整體向前推進一個。以此類推,循環節從第二個開始。

下證 循環節最後一位是 2k2k 。首先證明,對於一項 i+j1\frac{i+j}{1} ,如果其不爲第一項(即 i=0i=0 的時候),那麼 i=ki=k 。這是因爲 ki<1k-i<1ki0    kik-i\le 0\;\Leftrightarrow\;k\le i ,而 iki\le k ,就只好 i=ki=k 了。

考慮整個循環過程,一定形如

n=[0+k1,k+b1nk/1,b1+b2nb1/nk,,k+b1nk,]\sqrt{n}=\left[\frac{0+k}{1},\frac{k+b_1}{n_k/1},\frac{b_1+b_2}{n_{b_1}/n_k},\dots,\frac{k+b_1}{n_k},\dots\right]

顯然 k+b1nk\frac{k+b_1}{n_k} 的上一個數的分母是 11 。故其分子是 kk 。寫完整就是

n=[0+k1,k+b1nk,,k+k1,k+b1nk,]\sqrt{n}=\left[\frac{0+k}{1},\frac{k+b_1}{n_k},\dots,\frac{k+k}{1},\frac{k+b_1}{n_k},\dots\right]

明顯循環的最後一位是 2k2k ,得證。

3.PellPell 特解

n\sqrt{n} 寫成連分數,一定可以有遞歸形式

n=[a0;a1,a2,,ak1,a0+n]\sqrt{n}=[a_0;a_1,a_2,\dots,a_{k-1},a_0+\sqrt{n}]

設其漸進分數爲 p/q\langle p\rangle/\langle q\rangle ,則 n=pk1(a0+n)+pk2qk1(a0+n)+qk2\sqrt{n}=\frac{p_{k-1}(a_0+\sqrt{n})+p_{k-2}}{q_{k-1}(a_0+\sqrt{n})+q_{k-2}}

  {nqk1=a0pk1+pk2pk1=a0qk1+qk2\Leftrightarrow\;\begin{cases}nq_{k-1}=a_0p_{k-1}+p_{k-2}\\ p_{k-1}=a_0q_{k-1}+q_{k-2}\end{cases}

這告訴我們,nqk1pk1=[a0;a1,a2,,ak1,a0]\frac{nq_{k-1}}{p_{k-1}}=[a_0;a_1,a_2,\dots,a_{k-1},a_0]

2.4.4 中有結論 qkpk1pkqk1=(1)kq_kp_{k-1}-p_kq_{k-1}=(-1)^k ,將 {qk=pk1pk=nqk1\begin{cases}q_k=p_{k-1}\\p_{k}=nq_{k-1}\end{cases} 代入得 pk12nqk12=(1)kp_{k-1}^2-nq_{k-1}^2=(-1)^k

kk 爲偶數時,顯然 {x=pk1y=qk1\begin{cases}x=p_{k-1}\\y=q_{k-1}\end{cases}x2ny2=1x^2-ny^2=1 的解。在 kk 爲奇數時,利用 智婕《pellpell方程的求解技巧》 中介紹的方法,有 {x=2pk12+1y=2pk1qk1\begin{cases}x=2p_{k-1}^2+1\\y=2p_{k-1}q_{k-1}\end{cases} 的解(直接暴力代入也可證明)。

該解是讓 x+ynx+y\sqrt{n} 最小的解。

爲什麼是最小的解,我真的不知道了,找了好久了

4.PellPellkk 小解

以下內容源於馮志剛《初等數論》

3 中我們給出了特解 (x0,y0)(x_0,y_0) 。令 ϵ=x0+y0n\epsilon=x_0+y_0\sqrt{n} ,我們要說明,所有的解 x,yx,y 滿足

nN+,s.t.  ϵn=x+yn\therefore\exist n\in\N^+,\text{s.t.}\;\epsilon^n=x+y\sqrt{n}

反證法。設令一解是 (x,y)(x,y) ,一定

nN+,s.t.  ϵn<x+yn<ϵn+1\exist n\in\N^{+},\text{s.t.}\;\epsilon^n<x+y\sqrt{n}<\epsilon^{n+1}

ϵ1=x0y0n\epsilon^{-1}=x_0-y_0\sqrt{n} ,顯然 ϵ1ϵ=1\epsilon^{-1}\epsilon =1 。不等式同乘 (ϵ1)n(\epsilon^{-1})^n 得到

1<(x+yn)(ϵ1)n<ϵ1<(x+y\sqrt{n})(\epsilon^{-1})^n<\epsilon

(x+yn)(ϵ1)n=u+vn(uZ,vZ)(x+y\sqrt{n})(\epsilon^{-1})^n=u+v\sqrt{n}\quad(u\in\Z,v\in\Z) ,需要發現 (u,v)(u,v) 是一組解。證明極其簡單,由二項式展開可知 uvn=(xyn)ϵnu-v\sqrt{n}=(x-y\sqrt{n})\epsilon^n ,兩式相乘可證。

此時,由於 1<(x+yn)(ϵ1)n=u+vn1<(x+y\sqrt{n})(\epsilon^{-1})^n=u+v\sqrt{n} ,知

1>1u+vn=uvn>01>\frac{1}{u+v\sqrt{n}}=u-v\sqrt{n}>0

u+vn>1u+v\sqrt{n}>1 相加,知 2u>12u>1 ,即 u>0u>0 。又

2vn=(u+vn)(uvn)>11=02v\sqrt{n}=(u+v\sqrt{n})-(u-v\sqrt{n})>1-1=0

v>0v>0 。此時不難發現,(u,v)(u,v) 是一組正整數解,但 u+vn<ϵu+v\sqrt{n}<\epsilon ,與 (x0,y0)(x_0,y_0) 是最小解矛盾。

所以,第 kk 小的解 (x,y)(x,y) 滿足 x+yn=(x0+y0n)kx+y\sqrt{n}=(x_0+y_0\sqrt{n})^k

5.例題

傳送門 to VJ,直接是個板題。

#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

typedef long long int_;
int_ a[20000];
bool pell(int_ n,int_ &x0,int_ &y0){
	int_ m = int_(sqrt(n)+0.5);
	while(m*m > n) -- m;
	while((m+1)*(m+1)<=n) ++ m;
	if(m*m == n) return false;
	int_ p = 0, q = 1; int i = 0;
	for(; true; ++i){
		int_ b = q-p;
		b += (m-b)/q*q;
		if((a[i] = (b+p)/q) == 2*m)
			break; // 循環終了
		p = b, q = (n-b*b)/q;
	}
	p = 1, q = 0; x0 = (i --);
	for(int_ t; i>=0; --i,q=t)
		t = p, p = q+a[i]*p;
	if((x0&1)^1) x0 = p, y0 = q;
	else x0 = 2*p*p+1, y0 = 2*p*q;
	return true;
}

int_ n; // sqrt{n}
const int mod = 8191;
struct Complex{
	int_ x, y;
	Complex(int_ R,int_ I){
		x = R%mod, y = I%mod;
	}
};
Complex operator*(Complex &a,Complex &b){
	return
	Complex(a.x*b.x%mod
	+n*a.y%mod*b.y%mod,
	a.x*b.y%mod
	+a.y*b.x%mod);
}

Complex qkpow(Complex base,int q){
	Complex ans = base; -- q;
	for(; q; q>>=1,base=base*base)
		if(q&1) ans = base*ans;
	return ans;
}

int main(){
	int_ k, x0, y0;
	while(~scanf("%lld %lld",&n,&k)){
		if(pell(n,x0,y0) == false){
			puts("No answers can \
meet such conditions");
			continue;
		}
		Complex c(x0,y0);
		c = qkpow(c,k);
		printf("%lld\n",c.x);
	}
	return 0;
}

https://blog.csdn.net/wh2124335/article/details/8871535?locationNum=14&fps=1

https://blog.csdn.net/u011815404/article/details/88717125

https://www.cnblogs.com/The-Pines-of-Star/p/9878823.html

https://wenku.baidu.com/view/fc1eae0c1eb91a37f1115cb9.html

https://www.doc88.com/p-7897715410004.html

http://www.mathchina.net/dvbbs/dispbbs.asp?boardid=7&Id=2701&page=8&star=1

http://blog.sina.com.cn/s/blog_5191695101018n69.html

https://wenku.baidu.com/view/04f333a3a4e9856a561252d380eb6294dc882201.html1

http://www.cqvip.com/read/read.aspx?id=27279641

https://wenku.baidu.com/view/49b7417390c69ec3d5bb7584.html

https://wenku.baidu.com/view/7f8fb7d376a20029bd642d0a.html


  1. 不知道有沒有用? ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章