HDU - 1757 A Simple Math Problem 矩阵快速幂

来源:互联网 发布:php如何写短信接口 编辑:程序博客网 时间:2024/05/15 17:33

解题思路:借用过了别人写的。。
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

|f(10) | |a0 a1 a2 …a8 a9| |f(9)|
| f(9) | | 1 0 0 … 0 0| |f(8)|
| …..| = |.. … … … ..| | .. |
| f(2) | | 0 0 0 … 0 0| |f(1)|
| f(1) | | 0 0 0 … 1 0| |f(0)|

另A举证为10*10的举证,如上图。
可以推出:
(f(n),f(n-1),…,f(n-9))^(-1) = A^(n-9)*(f(9),f(8),…,f(0))^(-1)

#include<cstdio>#include<cstring>using namespace std;typedef long long ll;#define N 10struct Matrix{    ll mar[N][N];}a, b, tmp;ll n, mod;Matrix matrixMul(Matrix aa, Matrix bb) {    for(int i = 0; i < N; i++)        for(int j = 0; j < N; j++) {            tmp.mar[i][j] = 0;            for(int k = 0; k < N; k++)                tmp.mar[i][j] += (aa.mar[i][k] * bb.mar[k][j]) % mod;        }    return tmp;}void solve() {    while(n) {        if(n & 1)            b = matrixMul(b,a);        a = matrixMul(a,a);        n >>= 1;    }}int main() {    while(scanf("%I64d%I64d", &n, &mod) != EOF) {        for(int i = 0; i < N; i++)            for(int j = 0; j < N; j++)                a.mar[i][j] = b.mar[i][j] = 0;        for(int i = 0; i < N; i++)             b.mar[i][i] = 1;        for(int i = 1; i < N; i++)            a.mar[i][i-1] = 1;        for(int i = 0; i < N; i++)            scanf("%I64d", &a.mar[0][i]);        if(n <= 9) {            printf("%I64d\n", n);            continue;        }        n -= 9;        solve();        long long ans = 0;        for(int i = 0; i < N; i++)             ans += (b.mar[0][i] * (9 - i)) % mod;         printf("%I64d\n", ans % mod);    }    return 0;}
0 0
原创粉丝点击