1.佩尔方程:
形如x2-D*y2=1(D是一个固定的正整数且D不是完全平方数)的方程称为佩尔方程
2.佩尔方程定理:
佩尔方程总有正整数解,若(x1,y1)是使x1最小的解,则每个解(xk,yk)都可以通过取幂得到:
xk + yk*sqrt(D) = (x1 + y1*sqrt(D))k
也有:xn+1 = x0xn + Dy0yn, yn+1 = y0xn + x0yn;
xn+2 = 2x0xn+1-xn,yn+2 = 2x0yn+1-yn
3.连分数:
一个数字可以表示成以下形式:
称为连分数,简记为[a0,a1,a2,a3,a4,a5,a6]则
Pi = [3,7,15,1,292,1,1,1,2,1,3,1,14,2,1,1,2,……]
21/3 = [1,3,1,5,1,1,4,1,1,8,1,14,1,10,2,1,4,12,2,3,2,……]
21/2 = [1,2,2,2,2,2,2,2,2,2,2,2,2……]
e = [2,1,2,1,1,4,1,1,6,1,1,8,1,1,10,1,1,12,1,1,14……]
好吧……,懒得写了,粘我整理的模板吧……
//求出p2 - D * q2 = 1的基解(最小正整数解),这个可能溢出,有必要的话,用java, 写成类比较好
bool PQA(LLI D, LLI &p, LLI &q) {//来自于PQA算法的一个特例
LLI d = sqrt(D);
if ((d + 1) * (d + 1) == D) return false;
if (d * d == D) return false;
if ((d - 1) * (d - 1) == D) return false;//这里是判断佩尔方程有没有解
LLI u = 0, v = 1, a = int(sqrt(D)), a0 = a, lastp = 1, lastq = 0;
p = a, q = 1;
do {
u = a * v - u;
v = (D - u * u) / v;
a = (a0 + u) / v;
LLI thisp = p, thisq = q;
p = a * p + lastp;
q = a * q + lastq;
lastp = thisp;
lastq = thisq;
} while ((v != 1 && a <= a0));//这里一定要用do~while循环
p = lastp;
q = lastq;
//这样求出后的(p,q)是p2 – D * q2 = (-1)k的解,也就是说p2 – D * q2可能等于1也可能等于-1,如果等于1,(p,q)就是解,如果等于-1还要通过(p2 + D * q2,2 * p * q)来求解,如下
if (p * p - D * q * q == -1) {
p = lastp * lastp + D * lastq * lastq;
q = 2 * lastp * lastq;
}
return true;
}