HDU - 2604 Queuing(矩阵快速幂,推规律
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2604
题目描述:
题意:
由f和m构成一个长度为L的序列,求不存在fmf和fff的串的方案数,答案对mod取余。
思路:
通过列出前6项,F(1)=2
,F(2)=4
,F(3)=6
,F(4)=9
,F(5)=15
,F(6)=25
....
从而推出公式F(n)=F(n-1)+F(n-3)+F(n-4)
从而得到中间矩阵A, 答案(F(n)
)就是 Matrix ans = 的第一项 :ans.m[0][0]*ps:L为0的时候答案是0 * $
参考代码:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define ll long long #define endl '\n' #define mem(a,b) memset(a,b,sizeof(a)) const ll N=4; ll k,mod; struct Matrix { ll m[N][N]; Matrix() { mem(m, 0); } void init() { for (int i = 0; i < N; i++)m[i][i] = 1; } Matrix operator+(const Matrix &b) const { Matrix c; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { c.m[i][j] = (m[i][j] + b.m[i][j]) % mod; } } return c; } Matrix operator*(const Matrix &b) const { Matrix c; mem(c.m,0); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < N; k++) { c.m[i][j] = (c.m[i][j] + (m[i][k] * b.m[k][j]) % mod) % mod; } } } return c; } Matrix operator^(const ll &t) const { Matrix ans, a = (*this); ans.init(); ll n = t; while (n) { if (n & 1) ans = ans * a; a = a * a; n >>= 1; } return ans; } }; int main() { while (~scanf("%lld%lld", &k, &mod)) { if (k == 0) { printf("0\n"); } else if (k == 1) { printf("%d\n",2%mod); } else if (k == 2) { printf("%d\n",4%mod); } else if (k == 3) { printf("%d\n",6%mod); } else if (k == 4) { printf("%d\n",9%mod); } else { Matrix A; mem(A.m, 0); A.m[0][0] = A.m[0][2] = A.m[0][3] = 1; Matrix B; mem(B.m, 0); for (int i = 1; i < N; i++) { A.m[i][i - 1] = 1; } B.m[0][0] = 9, B.m[1][0] = 6, B.m[2][0] = 4, B.m[3][0] = 2; Matrix ans = (A ^ (k - 4)) * B; printf("%lld\n", ans.m[0][0] % mod); } } return 0; }