佩尔方程的最小解

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;
}

你可能感兴趣的:(数论)