HDU 3292 (佩尔方程 矩阵快速幂)

来源:互联网 发布:blued交友软件 编辑:程序博客网 时间:2024/05/18 03:35

题目链接:点击这里

题意:求解佩尔方程x2ny2=1的第k大解。

首先暴力求出佩尔方程的最小特解,然后根据迭代式子

[xkyk]=[x1y1d×y1x1]k1[x1y1]

直接用矩阵快速幂求出结果即可。

#include <bits/stdc++.h>using namespace std;#define maxn 500005#define INF 1e15#define mod 8191struct m {    long long a[2][2];    m operator * (const m &gg) const {        m ans;        memset (ans.a, 0, sizeof ans.a);        for (int i = 0; i < 2; i++) {            for (int j = 0; j < 2; j++) {                for (int l = 0; l < 2; l++) {                    ans.a[i][j] += a[i][l]*gg.a[l][j];                    ans.a[i][j] %= mod;                }            }        }        return ans;    }    void show () {        for (int i = 0; i < 2; i++) {            for (int j = 0; j < 2; j++)                cout << a[i][j] << " ";            cout << endl;        }    }};m qpow (m a, long long kk) {    m ans;    int i, j;    for(i = 0; i < 2; ++i)        for(j = 0; j < 2; ++j)            ans.a[i][j] = (i == j ? 1 : 0);    for(; kk; kk >>= 1) {        if(kk&1) ans = ans*a;        a = a*a;    }    return ans;}int n, k;void solve (long long x, long long y, long long k) {    m ans;    ans.a[0][0] = x, ans.a[0][1] = n*y;    ans.a[1][0] = y, ans.a[1][1] = x;    ans = qpow (ans, k-1);    cout << (x*ans.a[0][0]+y*ans.a[0][1]) % mod << endl;}int main () {    while (cin >> n >> k) {        if (n == 1 || n == 4 || n == 9 || n == 16 || n == 25) {            cout << "No answers can meet such conditions" << endl;            continue;        }        for (long long y = 1; ; y++) {            long long x = sqrt (1LL*n*y*y+1);            if (x*x-y*y*n == 1) { //cout << x << " " << y << endl;                solve (x, y, k);                goto out;            }        }        //cout << "No answers can meet such conditions" << endl;        out: ;    }    return 0;}
0 0
原创粉丝点击