題目連接php
題意:c++
思路:google
直接拿別人的圖,本身寫太麻煩了~3d
而後就能夠用矩陣快速冪套模板求遞推式啦~code
另外:blog
這題想不到或者不會矩陣快速冪,根本無法作,仍是2013年長沙邀請賽水題,也是2008年Google Codejam Round 1A的C題。get
#include <bits/stdc++.h> typedef long long ll; const int N = 5; int a, b, n, mod; /* *矩陣快速冪處理線性遞推關係f(n)=a1f(n-1)+a2f(n-2)+...+adf(n-d) */ struct Matrix { int row, col; ll arr[N][N]; Matrix(int r=0, int c=0) { row = r; col = c; memset (arr, 0, sizeof (arr)); } Matrix operator * (const Matrix &B) { Matrix ret(row, B.col); for (int i=0; i<row; ++i) { for (int j=0; j<B.col; ++j) { for (int k=0; k<col; ++k) { ret.arr[i][j] = (ret.arr[i][j] + (ll) arr[i][k] * B.arr[k][j]) % mod; } } } return ret; } void unit(int n) { row = col = n; for (int i=0; i<n; ++i) { arr[i][i] = 1; } } }; Matrix operator ^ (Matrix X, ll n) { Matrix ret; ret.unit (X.col); while (n) { if (n & 1) { ret = ret * X; } X = X * X; n >>= 1; } return ret; } int f[3], x[3]; int main() { while (scanf ("%d%d%d%d", &a, &b, &n, &mod) == 4) { double c = (double) a + sqrt ((double) b); f[1] = ((ll) ceil (c)) % mod; f[2] = ((ll) ceil (c*c)) % mod; int d = 2; x[1] = (2*a) % mod; x[2] = (-(a*a-b) % mod + mod) % mod; if (n <= d) { printf ("%d\n", f[n]); } else { Matrix Fn(d+1, d+1), Fd(d+1, 1); for (int i=0; i<Fn.row-1; ++i) { Fn.arr[i][i+1] = 1; } for (int i=1; i<Fn.col; ++i) { Fn.arr[Fn.row-1][i] = x[d-i+1]; } for (int i=0; i<Fd.row; ++i) { Fd.arr[i][0] = f[i]; } Fn = Fn ^ (n - d); Fn = Fn * Fd; printf ("%d\n", Fn.arr[d][0]); } } return 0; }