hdu 3292 No more tricks, Mr Nanguo

来源:互联网 发布:生化危机4mac版 编辑:程序博客网 时间:2024/06/05 13:22

            佩尔方程+矩阵快速幂。先暴力求出佩尔方程的特解(最小解),然后利用佩尔方程的矩阵递推式,推出第k项。

            

#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdio>#include<cmath>#include<map>#define LL long long#define REP(i, n) for(int i = 0; i < n; i ++)#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int N = 2;const int MOD = 8191;struct Matrix{    int m[N][N];}per, mul;int x, y, d;void search(){    y = 1;    while(true)    {        x = sqrt((double)d * y * y + 1);        if(x * x - d * y * y == 1)            break;        y ++;    }}void init(){    mul.m[0][0] = x % MOD;    mul.m[0][1] = d * y % MOD;    mul.m[1][0] = y % MOD;    mul.m[1][1] = x % MOD;    REP(i, 2) REP(j, 2)        per.m[i][j] = (i == j);}Matrix Mul(Matrix a, Matrix b){    Matrix c;    REP(i, 2) REP(j, 2)    {        c.m[i][j] = 0;        REP(k, 2)            c.m[i][j] += a.m[i][k] * b.m[k][j];        c.m[i][j] %= MOD;    }    return c;}Matrix Pow(Matrix a, int b){    Matrix ret = per;    while(b)    {        if(b & 1)        {            ret = Mul(ret, a);        }        a = Mul(a, a);        b >>= 1;    }    return ret;}int main(){    int k, ans;    while(scanf("%d%d", &d, &k) != EOF)    {        int tmp = sqrt(d + 0.0);        if(tmp * tmp == d)        {            puts("No answers can meet such conditions");            continue;        }        search();        init();        Matrix ma = Pow(mul, k - 1);        ans = ma.m[0][0] * x % MOD + ma.m[0][1] % MOD * y % MOD;        printf("%d\n", ans % MOD);    }}