說明:
文中的分數 qp 不一定滿足 gcd(p,q)=1 ,也未必 p,q∈Z 。
由於結論是需要證明的,所以結論用 ∴ 作開頭,以強調。
1.概述
有關 x,y 的方程 x2−ny2=1(n∈Z,n=0)
被稱爲 Pell 方程。我們要處理的是 x,y 的正整數解。
不難發現,n<0 時,無正整數解;在 n=0 時,額……;在 n>0 且 n∈Z 時,令 t=yn∈N+ ,方程轉化爲 x2−t2=1 ,無正整數解。
所以,我們實際上考慮的是
∴x2−ny2=1(x,y,n∈N+,n∈Z)
2.連分數
推薦刊物:數學吧之連分數,蠻不錯的。
1.定義
我們僅研究簡單連分數 a0+a1+a2+a3+⋯111
可能是有限的,也可能是無限的。用一種更簡單的形式表達,可寫成
[a0;a1,a2,…]
倘若有限,一般會給出項數 [a0;a1,a2,…,ak]
2.計算
顯然我們有 [a0;a1,a2,…,ak]=a0+[a1;a2,a3,…,ak]1
也可能是無限連分數。但是,倘若 [a1;a2,a3,…,ak]=qp
(或者所謂的 limk→+∞[a1;a2,a3,…,ak]=qp ),那麼我們有
∴[a0;a1,a2,…,ak]=pq+a0p
3.漸進分數
1.定義
定義一個連分數 a 的 k 階漸進分數 qkpk=[a0;a1,a2,…,ak]
注意,原連分數的長度可能是任意一個不小於 k 的值,或者是無限連分數。
2.性質
對於任意 k(k≥2) ,我們有
∴{pk=akpk−1+pk−2qk=akqk−1+qk−2
該定理可以使用數學歸納法證明。在 k=2 時不難驗證;對於 k(k>2) 的情況,記連分數 a′=[a1;a2,a3,…,ak] 的漸進分數爲 q′p′ ,由歸納法有
{pk′=akpk−1′+pk−2′qk′=akqk−1′+qk−2′
而 2.3
告訴我們
{pk=a0pk′+qk′qk=pk′
將角標換成 k−1 或 k−2 自然也成立。進一步推導有
pk=a0(akpk−1′+pk−2′)+(akqk−1′+qk−2′)=ak(a0pk−1′+qk−1′)+(a0pk−2′+qk−2′)=akpk−1+pk−2
q 便不展開了,可自證,無任何難度。
3.新的約定
我們規定
{p−1=1q−1=0,{p−2=0q−2=1
這會使得 2.3.2
對於任意 k∈N 都成立。
4.重要結論
將 2.3.2
中的公式,上式乘 qk−1 得到
pkqk−1=akpk−1qk−1+pk−2qk−1(1)
下式乘 pk−1 得到
qkpk−1=akqk−1pk−1+qk−2pk−1(2)
(2) 式 −(1) 式得到
qkpk−1−pkqk−1=−(qk−1pk−2−pk−1qk−2)
左右兩邊的形式是相仿的,我們可以定義新數列 {qnpn−1−pnqn−1} ,結合首項 q0p−1−p0q−1=1 推出
∴qkpk−1−pkqk−1=(−1)k
4.逼近無理數
楊中和《二次無理數的連分數》講的非常清楚,嚴謹。果然還是要看專業文獻。
設我們正在展開 cn+b ,滿足 b∈Z,c∈N+ 。不妨設其值爲 a+r1 ,其中 a∈Z ,而 r 是另一個連分數。由於 r∈(1,+∞)⇔r1∈(0,1) ,我們要取最大的 a ,具體方案是
maximizeb′≤n,s.t.c∣(b+b′)
然後我們就有
a=cb+b′r=(n−b′⋅b′)/cn+b′
r 是化簡後的結果。分母有理化就不在這裏進行了。下證 cn−b′⋅b′∈N+ 。
- 注意到 b′≡−b(modc) ,故 n−b′⋅b′≡n−b2(modc) 。該值爲正是顯然的,因爲 b′≤n 。
- 利用數學歸納法,b=0∧c=1 時顯然成立。設 c′=(n−b′⋅b′)/c ,則 (n−b′⋅b′)/c′=c∈Z ,故得證。
那麼,這個連分數有多長呢?答案是,一定會出現循環。不難發現,如果 cn+b 在之前出現過,那麼就循環了。我們的算法中,b≤n ,而且該值 >1 ,推出 2n≥n+b>c 。不同形式有限,鴿籠原理,必定有循環。
爲了讓整個過程更直觀,令 k=⌊n⌋ ,再令 nx=n−x2 ,我們有
n=[k;nkk+i1,ni1/nki1+i2,⋯,pj1+i,ni/pi+j2,⋯]
現在我們來揭示這個連分數的一些規律,以其中的任意兩項 pj1+i,ni/pi+j2 作代表。
- 兩個相鄰的分母,乘積爲共有的分子的過渡數 ni 。
另外一個比較重要的結論是:
- 由於該比值爲正整數,所以 p≤j1+i≤k+i ,也有 ni/p≤i+j2≤k+i 。
- 由於 i 充分大,所以 p>k−i ,否則 i 可以再增大 p 。
- 注意到 ni>k2−i2=(k−i)(k+i) ,故 pni>k+i(k−i)(k+i)=k−i 。
- 綜上:p,pni∈(k−i,k+i] 。換言之,兩個相鄰分母在 k 的鄰域裏,半徑爲共有因子。
然後我們可以證明,循環節從第二個開始。使用反證法。假設循環從 l 始,由 r 終。
n=[…,c′b′+bl,clbl+bl+1,…,crbr+bl,clbl+bl+1,…]
由之前的結論,c′⋅cl=n−bl2 且 cr⋅cl=n2−bl2 ,所以 c′=cr 。
用上 c′=cr 的結論,由於 c′b′+bl 和 crbr+bl 都是整數,所以 b′≡br(modc′) 。
之前證明過了 k−br<c′ 與 k−b′<c′ 。在 b′=br+c′ (或者更大)時,b′>(k−c′)+c′=k ,矛盾;在 b′=br−c′ (或者更小)時,c′>k−(br−c′)⇔k−br<0 不可能成立。
所以我們有了重要結論 {b′=brc′=cr
所以循環可以從 b′,c′ 開始,到 br−1,cr−1 結束——循環整體向前推進一個。以此類推,循環節從第二個開始。
下證 循環節最後一位是 2k 。首先證明,對於一項 1i+j ,如果其不爲第一項(即 i=0 的時候),那麼 i=k 。這是因爲 k−i<1 即 k−i≤0⇔k≤i ,而 i≤k ,就只好 i=k 了。
考慮整個循環過程,一定形如
n=[10+k,nk/1k+b1,nb1/nkb1+b2,…,nkk+b1,…]
顯然 nkk+b1 的上一個數的分母是 1 。故其分子是 k 。寫完整就是
n=[10+k,nkk+b1,…,1k+k,nkk+b1,…]
明顯循環的最後一位是 2k ,得證。
3.Pell 特解
將 n 寫成連分數,一定可以有遞歸形式
n=[a0;a1,a2,…,ak−1,a0+n]
設其漸進分數爲 ⟨p⟩/⟨q⟩ ,則 n=qk−1(a0+n)+qk−2pk−1(a0+n)+pk−2
⇔{nqk−1=a0pk−1+pk−2pk−1=a0qk−1+qk−2
這告訴我們,pk−1nqk−1=[a0;a1,a2,…,ak−1,a0]
而 2.4.4
中有結論 qkpk−1−pkqk−1=(−1)k ,將 {qk=pk−1pk=nqk−1 代入得 pk−12−nqk−12=(−1)k
在 k 爲偶數時,顯然 {x=pk−1y=qk−1 是 x2−ny2=1 的解。在 k 爲奇數時,利用 智婕《pell方程的求解技巧》 中介紹的方法,有 {x=2pk−12+1y=2pk−1qk−1 的解(直接暴力代入也可證明)。
該解是讓 x+yn 最小的解。
爲什麼是最小的解,我真的不知道了,找了好久了
4.Pell 第 k 小解
以下內容源於馮志剛《初等數論》。
在 3
中我們給出了特解 (x0,y0) 。令 ϵ=x0+y0n ,我們要說明,所有的解 x,y 滿足
∴∃n∈N+,s.t.ϵn=x+yn
反證法。設令一解是 (x,y) ,一定
∃n∈N+,s.t.ϵn<x+yn<ϵn+1
令 ϵ−1=x0−y0n ,顯然 ϵ−1ϵ=1 。不等式同乘 (ϵ−1)n 得到
1<(x+yn)(ϵ−1)n<ϵ
設 (x+yn)(ϵ−1)n=u+vn(u∈Z,v∈Z) ,需要發現 (u,v) 是一組解。證明極其簡單,由二項式展開可知 u−vn=(x−yn)ϵn ,兩式相乘可證。
此時,由於 1<(x+yn)(ϵ−1)n=u+vn ,知
1>u+vn1=u−vn>0
與 u+vn>1 相加,知 2u>1 ,即 u>0 。又
2vn=(u+vn)−(u−vn)>1−1=0
故 v>0 。此時不難發現,(u,v) 是一組正整數解,但 u+vn<ϵ ,與 (x0,y0) 是最小解矛盾。
所以,第 k 小的解 (x,y) 滿足 x+yn=(x0+y0n)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;
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.html
http://www.cqvip.com/read/read.aspx?id=27279641
https://wenku.baidu.com/view/49b7417390c69ec3d5bb7584.html
https://wenku.baidu.com/view/7f8fb7d376a20029bd642d0a.html