Pell方程

pell方程

1.形式:x^2 - dy^2 =1

2.递推形式:

设的渐近分数列,由连分数理论知存在使得(pi,qi)为佩尔方程的解。取其中最小的,将对应的 (pi,qi)称为佩尔方程的基本解,或最小解,记作(x1,y1),则所有的解(xi,yi)可表示成如下形式:

或者由以下的递回关系式得到:

3.求解最小解

1)暴力枚举y的值,对等式做判定

2)通过d^{1/2}的连分数表示确定最小解

连分数构造方法:

Pell方程_第1张图片

 

4.应用

1)求最小特解

POJ :3292


import java.math.BigInteger;
import java.util.Scanner;

public class Main
{
    public static void solve(int n)
    {
        BigInteger N, p1, p2, q1, q2, a0, a1, a2, g1, g2, h1, h2,p,q;
        g1 = q2 = p1 = BigInteger.ZERO;
        h1 = q1 = p2 = BigInteger.ONE;
        a0 = a1 = BigInteger.valueOf((int)Math.sqrt(1.0*n));
        BigInteger ans=a0.multiply(a0);
        if(ans.equals(BigInteger.valueOf(n)))
        {
            System.out.println("No solution!");
            return;
        }
        N = BigInteger.valueOf(n);
        while (true)
        {
            g2 = a1.multiply(h1).subtract(g1);
            h2 = N.subtract(g2.pow(2)).divide(h1);
            a2 = g2.add(a0).divide(h2);
            p = a1.multiply(p2).add(p1);
            q = a1.multiply(q2).add(q1);
            if (p.pow(2).subtract(N.multiply(q.pow(2))).compareTo(BigInteger.ONE) == 0) break;
            g1 = g2;h1 = h2;a1 = a2;
            p1 = p2;p2 = p;
            q1 = q2;q2 = q;
        }
        System.out.println(p+" "+q);
    }

    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        while(cin.hasNextInt())
        {
            solve(cin.nextInt());
        }
    }
} 

2)求第K解 HDU 3292

求出特解后,进行矩阵快速幂(注意当d为完全平方数时只有平凡解(\pm 1,0) )。

第K解:

$$ \left[ \begin{matrix} xi\\ yi \\ \end{matrix} \right] \tag{3} $$ = $$ \left[ \begin{matrix} x1&dy1 \\ y1 & x1 \end{matrix} \right] \tag{3} $$ ^{k-1} * $$ \left[ \begin{matrix} x1 \\ y1 \end{matrix} \right] \tag{3} $$

code:

#include 
using namespace std;
//#define N 100010
#define LL long long
#define PB push_back
#define pii pair
#define MP make_pair

typedef unsigned long long ull;
typedef long long ll;

const int maxn = 3e5 + 10;
const int mod = 8191;

struct mat
{
    int s[2][2];
};

mat mul(mat a, mat b)
{
    mat c;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++){
            c.s[i][j] = 0;
            for (int k = 0; k < 2; k++)
            {
                c.s[i][j] += a.s[i][k] * b.s[k][j];
                c.s[i][j] %= mod;
            }
        }
    return c;
}

mat qpow(mat a, int b)
{
    mat c;
    c.s[0][0] = c.s[1][1] = 1;
    c.s[1][0] = c.s[0][1] = 0;
    while (b)
    {
        if (b & 1)
            c = mul(c, a);
        a = mul(a, a);
        b >>= 1;
    }
    return c;
}

pii solve(ll n)
{
    ll N, p1, p2, q1, q2, a0, a1, a2, g1, g2, h1, h2, p, q;
    g1 = q2 = p1 = 0;
    h1 = q1 = p2 = 1;
    a0 = a1 = sqrt(n * 1.0);
    ll ans = a0 * a0;
    N = n;
    // cout<

 

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