佩尔方程+矩阵快速幂整理

佩尔方程最基本的形式(我目前了解到的):

x2 - d × y2 = 1

 

首先找到一组最小正整数解:(x1,y1)

解的递推式为:

Xn  = Xn-1  × X1 + d × Yn-1 ×Y1

Yn  = Xn-1  × Y1 + Yn-1  × X1

 

矩阵快速幂递推:

 

例题:佩尔方程+矩阵快速幂(HDU3292)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod = 8191;

struct matrix
{
    int m[2][2];
    matrix()
    {
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                m[i][j] = 0;
        m[1][1] = 1;
        m[0][0] = 1;
    }
    matrix operator *(const matrix& a) const
    {
        matrix temp;
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
            {
                temp.m[i][j] = 0;
                for(int k=0;k<2;k++)
                {
                    temp.m[i][j]+=m[i][k]*a.m[k][j]%mod;
                    temp.m[i][j]%=mod;
                }
            }
        }
        return temp;
    }
};

matrix ks(matrix a,int b)
{
    matrix ans = matrix();
    while(b)
    {
        if(b&1)
        {
            ans = ans*a;
        }
        a = a*a;
        b>>=1;
    }
    return ans;
}

//传入d后暴力求解
pair<int,int> find(int d)
{
    int x,y = 1;
    while(1)
    {
        ll tmp = (ll)y*y*d+1;
        int temp = sqrt(tmp);
        if((ll)temp*temp==tmp)
        {
            x = temp;
            break;
        }
        y++;
    }
    return make_pair(x,y);
}


int main()
{
    int n,k;
    while(scanf("%d %d",&n,&k)!=EOF)
    {
        int temp = sqrt(n*1.0);
        if(temp*temp == n)
        {
            printf("No answers can meet such conditions\n");
            continue;
        }
        pair<int,int> base = find(n);
        int x1 = base.first,y1 = base.second;
        //printf("%d %d\n",base.first,base.second);
        matrix d;
        d.m[0][0] = x1;
        d.m[0][1] = n * y1;
        d.m[1][0] = y1;
        d.m[1][1] = x1;
        matrix ans = ks(d,k-1);
        int ansx = (ans.m[0][0]*x1%mod+ans.m[0][1]*y1%mod)%mod;
        int ansy = (ans.m[1][0]*x1%mod+ans.m[1][1]*y1%mod)%mod;
        printf("%d\n",ansx);
    }
}
View Code

 

posted @ 2018-08-06 11:02  GoesOn  阅读(480)  评论(0编辑  收藏  举报