佩尔方程
2016-02-17 10:31
190 查看
佩尔方程(Pell Equation)为:
其中d不为完全平方数且d>1.
如果已知它的最小特解:x1,y1
那么存在迭代公式:
通过简单的证明:
由此得到矩阵递推式:
暴力法寻找最小特解:
hdu 3292 No more tricks, Mr Nanguo
http://acm.hdu.edu.cn/showproblem.php?pid=3292
大意:转化题意,即x^2-NY^2=1 求出第K个X解
分析:先暴力法求出特解,然后,Pell方程的解递推矩阵求出答案
连分数:
佩尔方程:
,随着Y的增大,有关系:
因为d不是完全平方数,所以
可写成连分数的形式. 将该连分数表示成
称之为第n个渐进值。
存在:
POJ 2427 Smith's Problem
http://poj.org/problem?id=2427
大意:求解满足佩尔方程的一对值。数据很大。
连分数求解Pell方程,代码写不出来,参考他人。。
hdu 2281 Square Number
http://acm.hdu.edu.cn/showproblem.php?pid=2281
Find the biggest integer n (1 <= n <= N) and an integer x to make them satisfy
分析:关于平方数之和有一个公式,下面是推导,加深印象。
同时,
所以
所以,上面的等式就等价于:
其中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
http://poj.org/problem?id=2427
大意:求解满足佩尔方程的一对值。数据很大。
连分数求解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
http://acm.hdu.edu.cn/showproblem.php?pid=2281
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); } } }
相关文章推荐
- Oracle SSL支持和keystore的生成
- php 之跨域上传图片 (smallnews笔记)
- 深入分析JavaWeb 18 -- JavaWeb的两种常用开发模式
- 电力企业计量生产运行系统总体解决方案
- 创建COM对象
- php fopen file_get_contents curl区别
- 如何用三个月时间获得三年经验
- 免密码自动生成ssh key
- linux环境配置java web项目之四——安装数据库
- Extjs二级联动
- Java 环境变量
- iOS清除xcode缓存和生成文件
- 度转度分秒、度分秒转度
- 一天一点xib:8高冷的xib
- 分布式事务
- 笔记
- 抽象数据类型之容器(二)
- 集电极开路、漏极开路、上拉电阻、下拉电阻等接口相关基本概念
- 表格换色
- Android资源的离线方式