佩尔方程

本文探讨了佩尔方程的性质,重点在于当d不是完全平方数且d>1时,如何寻找其最小特解x1, y1。通过对佩尔方程的深入分析,阐述了解决这类方程的方法及其在数论中的重要应用。" 82025759,1009978,深度学习在人脸检测与对齐的应用,"['深度学习', '计算机视觉', '人脸识别', '图像处理']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

佩尔方程(Pell Equation)为: 其中d不为完全平方数且d>1.
如果已知它的最小特解:x1,y1

那么存在迭代公式:

通过简单的证明:

由此得到矩阵递推式:


暴力法寻找最小特解:
typedef long long LL;
void search(LL &x,LL &y,LL d){
    y=1;
    while(1>0){
        x=(LL)sqrt(1+d*y*y);
        if(x*x-d*y*y==1) break;
        y++;
    }
}

hdu 3292  No more tricks, Mr Nanguo
http://acm.hdu.edu.cn/showproblem.php?pid=3292
大意:转化题意,即x^2-NY^2=1 求出第K个X解
分析:先暴力法求出特解,然后,Pell方程的解递推矩阵求出答案
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int mod=8191;
struct matrix{
    int m[2][2];
}A;
matrix I={
1,0,
0,1
};
void get(int &x,int &y,int n){
    for(y=1;;y++){
        int sum=n*y*y+1;
        x=(int)sqrt(sum);
        if(x*x==sum) break;
    }
}
matrix multi(matrix a,matrix b){
    matrix ans;
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            ans.m[i][j]=0;
            for(int k=0;k<2;k++){
                ans.m[i][j]+=a.m[i][k]*b.m[k][j];
            }
            ans.m[i][j]%=mod;
        }
    }
    return ans;
}
matrix power(int p){
    matrix ans=I,temp=A;
    while(p){
        if(p&1) ans=multi(ans,temp);
        temp=multi(temp,temp);
        p>>=1;
    }
    return ans;
}
int main()
{
    int n,k;
    while(cin>>n>>k){
        int nn=int(sqrt(n));
        if(nn*nn==n) {
            printf("No answers can meet such conditions\n");
            continue;
        }
        int x,y;
        get(x,y,n);
        if(k==1){
            printf("%d\n",x%mod);
            continue;
        }
        A.m[0][0]=x%mod;  A.m[0][1]=n*y%mod;
        A.m[1][0]=y%mod;  A.m[1][1]=x%mod;
        A=power(k-1);
        printf("%d\n",(A.m[0][0]*x%mod+A.m[0][1]*y%mod)%mod);
    }
    return 0;
}

连分数:

佩尔方程:  ,随着Y的增大,有关系:  
因为d不是完全平方数,所以 可写成连分数的形式. 将该连分数表示成   称之为第n个渐进值。
存在:


POJ 2427  Smith's Problem
大意:求解满足佩尔方程的一对值。数据很大。
连分数求解Pell方程,代码写不出来,参考他人。。
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());
        }
    }
}  

hdu 2281  Square Number
Find the biggest integer n (1 <= n <= N) and an integer x to make them satisfy

分析:关于平方数之和有一个公式,下面是推导,加深印象。

同时,

所以

所以,上面的等式就等价于:


import java.math.BigInteger;
import java.util.*;

public class Main
{
    static BigInteger x,y;
    public static void solve(long n)
    {
        BigInteger limit=BigInteger.valueOf(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*48));
        N = BigInteger.valueOf(48);
        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){
                BigInteger t=p.subtract(BigInteger.valueOf(3)).divide(BigInteger.valueOf(4));
                if(t.compareTo(limit)>0) break;
                if(t.multiply(BigInteger.valueOf(4)).add(BigInteger.valueOf(3)).equals(p)){
                    x=t;
                    y=q;
                }
            }
            g1 = g2;h1 = h2;a1 = a2;
            p1 = p2;p2 = p;
            q1 = q2;q2 = q;
        }
    }
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        long val;
        while(cin.hasNextLong())
        {
            val=cin.nextLong();
            if(val==0) break;
            x=BigInteger.ZERO;
            y=BigInteger.ZERO;
            solve(val);
            System.out.println(x+" "+y);
        }
    }
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值