AOJ 401 Fibonacci & GCD

来源:互联网 发布:js所有方法 编辑:程序博客网 时间:2024/06/06 00:54

给定m,n求gcd(fib(m),fib(n))

利用具体数学里面的一个公式,可以转化成求fib(gcd(m,n)),不过题目给的范围到了10^9,因此这里要采用矩阵连乘法来求斐波那契数。

第一次写矩阵快速幂,写的比较挫

#include <iostream>#include <cstring> #define mm 10003 using namespace std; struct mat {    int data[2][2];    mat() {        memset(data,0,sizeof(data));    };    mat(int a,int b,int c,int d) {        data[0][0] = a; data[0][1] = b; data[1][0] = c; data[1][1] = d;    };};  mat operator* (mat a,mat b) {    mat c;    c.data[0][0] = a.data[0][0] * b.data[0][0] + a.data[0][1] * b.data[1][0];    c.data[1][0] = a.data[1][0] * b.data[0][0] + a.data[1][1] * b.data[1][0];    c.data[0][1] = a.data[0][0] * b.data[0][1] + a.data[0][1] * b.data[1][1];    c.data[1][1] = a.data[1][0] * b.data[0][1] + a.data[1][1] * b.data[1][1];    c.data[0][0] %= mm; c.data[1][1] %= mm; c.data[1][0] %= mm; c.data[0][1] %= mm;    return c;} mat pow(mat a,int n) {    if(n == 1) return a;    if(n == 2) return a * a;    mat ans = pow(a * a,n >> 1);    if(n & 1) ans = ans * a;    return ans;} int fib(int n) {    if(n <= 2) return 1;    else {        mat ans = pow(mat(1,1,1,0),n - 2);        return ans.data[0][0] + ans.data[0][1];    }} int gcd(int a,int b) {    return (b == 0) ? a : gcd(b, a % b);} int main() {    int m,n;    while(cin >> m >> n , m || n) {        cout << fib(gcd(m,n)) % mm << endl;    }    return 0;}

 

0 0
原创粉丝点击