佩尔方程
佩尔方程:
形如x2-D*y2=1(D是一个固定的正整数且D不是完全平方数)的方程称为佩尔方程
佩尔方程定理:
佩尔方程总有正整数解,若(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
代码:
//求出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;
}
扩展
1. x2 - D * y2 = -1(D不是完全平方数)
这个方程并不一定有解,但若有解,则有无数解(这里的解说的都是正整数解)
且有:xn+1 = (x0² + Dy0²)xn+ 2Dx0y0yn, yn+1 = 2x0y0xn+ (x0² + Dy0²)yn ((x0,y0)是基解)
这种情况下,依旧使用上面的算法,如果最后求出的p和q满足p2 – D * q2 = -1则必然有解,否则无解
其中,若D是素数且D = 4 * k + 1,则必有解
2. x² - Dy² = K(D不是完全平方数 && |K| != 1)
这个方程并不一定有解,但若有解,则有无数解,待续