hdu-3292-佩尔方程+矩阵快速幂

这个题理解完了可以提取出x^2-n*d^2=1这个式子,一看就是典型的佩尔方程,然后求解第k项就行了。

要注意n是完全平方数的时候无解。

求最小特解用的暴力

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long int ll;
const int mod=8191;
int n,k;
ll x,y;
ll s[2][2];

void solve(ll &x,ll &y)
{
    y=1;
    while(1)
    {
        x=(ll)sqrt(1.0+n*y*y);
        if(x*x-n*y*y==1) break;
        y++;
    }
    s[0][0]=1;//这个初始数组一定要记得初始化QAQ
    s[0][1]=0;
    s[1][0]=0;
    s[1][1]=1;
}

void mul(ll a[][2],ll b[][2])
{
    ll c[2][2]= {0,0,0,0};
    for(int k=0; k<2; k++)
        for(int i=0; i<2; i++)
            for(int j=0; j<2; j++)
                c[i][j]=(c[i][j]+(a[i][k]*b[k][j])%mod)%mod;
    memcpy(a,c,sizeof(c));
}

void qp(ll num)
{
    ll T[2][2]= {x%mod,n*y%mod,y%mod,x%mod};//存进去时候最好也初始化mod一下
    while(num)
    {
        if(num%2) mul(s,T);
        mul(T,T);
        num/=2;
    }
}

int main()
{
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n==4 || n==9 || n==16 || n==25)
        {
            printf("No answers can meet such conditions\n");
            continue ;
        }
        solve(x,y);//暴力求解最小的特解
        qp(k-1);
        printf("%lld\n",(x*s[0][0]%mod+y*s[0][1]%mod)%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/alusang/article/details/81273444
今日推荐