数论知识之佩尔方程

佩尔方程

解决问题:

一般解决中解的问题。在大多数的时候都不会给你这个式子,要有你自己来推成这个形式。

一定要注意当n为平方数的时候无解

解决方法:

一般都要你推出最小解(可以用程序跑出来第一个),计为(x[1],y[1])。然后再用递推公式来求解

 

佩尔方程求解:

 

x^2 - n*y^2 = 1

 

x[i+1] = x[1]*x[i] + n* y[1]*y[i]

 

y[i+1] = x[1]*y[i] + y[1]*x[i]

例题1:

传送门

找出最大的整数n(1 <= n <= N)和整数x以使它们满足

输入项输入包含几个测试用例。每个测试用例包含一个整数N,1 <= N <= 10 ^ 18。输入以N = 0结尾。输出量在每种情况的一行中,输出您找到的两个整数n和x。样本输入

1
2
0

样本输出

1 1
1 1

 

 

#include<iostream>
#include<algorithm>
#include<vector> 
using namespace std; 
typedef long long ll;
typedef __int128 hll;
const int maxn=1e4+100;
vector<ll> v;
ll ans[maxn];
ll n;
//x^2==(n+1)*(2*n+1)/6
//(4+3)^2-48x^2=1
//先找到一个x,n
//然后再用跌代公式做

//x^2 - n*y^2 = 1
//x[i+1] = x[1]*x[i] + n* y[1]*y[i]
//y[i+1] = x[1]*y[i] + y[1]*x[i]
 
int main(){
    hll x=7,y=1;
    while((x-3)/4<=1e18){
        if((x-3)%4==0){
            ans[v.size()]=y;
            v.push_back((x-3)/4);
        }
        hll x1=x,y1=y;
        x=7*x1+48*y1;
        y=7*y1+x1;
    } 
    while(scanf("%lld",&n)&&n){
        int p=upper_bound(v.begin(),v.end(),n)-v.begin()-1;
        printf("%lld %lld\n",v[p],ans[p]);
    }
} 

 

 












例二:
传送门
如果三角形满足边长为连续的整数t-1,t,t + 1,并且面积为整数,则为Heron三角形。现在,对于给定的n,您需要找到与最小t
大于或等于n的苍鹭三角形 
输入项输入包含多个测试用例。多重输入的第一行是整数T(1≤T≤30000),后跟T行。每行包含一个整数N(1≤N≤10 ^ 30)。
输出量对于每个测试用例,输出一行中最小的t。如果所需的苍鹭三角形不存在,则输出-1。样本输入
4
1
2
3
4
样本输出
4
4
4
4

题意

给定一个整数 N(1N1^30),求最小的整数 t,要求 tN,使得边长为 t1,t,t+1 的三角形面积为整数。

 

 

#include<iostream>
#include<algorithm>
#include<vector> 
using namespace std; 
typedef long long ll;
typedef __int128 hll;
const int maxn=1e3+100;
__int128 xx[maxn],yy[maxn]; 
//x^2-3y^2=1 .
/*
x^2 - n*y^2 = 1
x[i+1] = x[1]*x[i] + n* y[1]*y[i]
y[i+1] = x[1]*y[i] + y[1]*x[i]
*/ 
void read(__int128 &x) {//__int128的板子
    x = 0;
    char ch;
    int flag = 1;
    while (ch = getchar()) {
        if (ch == '-') flag = -1;
        if (ch >= '0' && ch <= '9') break;
    }
    x = ch-'0';
    while ((ch = getchar()) >= '0' && ch <= '9') {
        x = x*10 + ch-'0';
    }
    x *= flag;
}


void out(__int128 x) {
    if (x < 0) {
        x = -x;
        putchar('-');
    }
    if (x >= 10) out(x / 10);
    putchar(x % 10 +'0');
}

void inint(){
    xx[1]=2,yy[1]=1;
    for(int i=2;i<=100;i++){
        xx[i]=xx[i-1]*2+yy[i-1]*3;
        yy[i]=yy[i-1]*2+xx[i-1];
    }
} 
int main(){
    int t;
    cin>>t;
    inint();
    while(t--){
        __int128 n;
        read(n);
        for(int i=1;i<=100;i++){
            if(xx[i]*2>=n){
                out(xx[i]*2);
                cout<<endl;
                break;
            }
        }
    }
    return 0;
}

 

 









 

根据海伦公式:S=p(pa)(pb)(pc)S=p(p−a)(p−b)(p−c)p=a+b+c2p=a+b+c2.

代入,令 t2=xt2=x,化简得 S2=3x2(x21)S2=3x2(x2−1).

题目要求 SS 为整数,则 (x21)(x2−1) 一定是3乘以一个平方数,

即 x21=3y2x2−1=3y2,即 x23y2=1x2−3y2=1.

易知最小解为(2, 1),用递推式求出其他解即可。

由于题目 NN 的范围较大,到 1e30,可以使用 int128(1e38),本地测试1e38内,只有67个解。

 
posted @ 2020-10-21 23:14  哎呦哎(iui)  阅读(1097)  评论(0编辑  收藏  举报