题意就是有长度为L的序列,每位的取值可以是'f'或者'm',问不包含'fff'和'fmf'的个数。
打表找规律
不难找出递推公式为F[n] = F[n-1] + F[n-3] + F[n-4]。
然后直接遍历就可以了...突然发现L范围很小,我写了个矩阵快速幂...
多组数据且模数不固定,矩阵快速幂即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 int n,mod; 6 7 struct M { 8 ll p[4][4]; 9 M(int num) { 10 memset(p,0,sizeof p); 11 for (int i = 0; i < 4; i++) { 12 p[i][i] = num; 13 } 14 } 15 16 M operator * (M b) { 17 M c(0); 18 for (int i = 0; i < 4; i++) { 19 for (int j = 0; j < 4; j++) { 20 c.p[i][j] = 0; 21 for (int k = 0; k < 4; k++) { 22 c.p[i][j] = (c.p[i][j] + (p[i][k]*b.p[k][j])%mod)%mod; 23 24 } 25 } 26 } 27 return c; 28 } 29 30 M operator ^ (ll k) { 31 M c(1),a = *this; 32 while (k) { 33 if (k&1) { 34 c = a*c; 35 } 36 a = a*a; 37 k >>= 1; 38 } 39 return c; 40 } 41 42 }; 43 M a(0),b(0); 44 int solve() { 45 M c(0); 46 47 if (n == 0) { 48 return 0; 49 } else if (n <= 4) { 50 return a.p[4-n][0]%mod; 51 } 52 c = b^(n-4); 53 c = c*a; 54 return c.p[0][0]%mod; 55 } 56 57 string s; 58 59 void db() { 60 for (int i = 1; i <= 15; i++) { 61 int p = pow(2.0,i),tot = 0,cnt = 0; 62 for (int j = 0; j < p; j++) { 63 int tmp = 1; 64 s = ""; 65 for (int k = 1; k <= i; k++) { 66 if (tmp&j) { 67 s += 'f'; 68 } else { 69 s += 'm'; 70 } 71 tmp <<= 1; 72 } 73 for (int k = 0; k < int(s.size())-2; k++) { 74 if (s[k] =='f' && s[k+1] == 'm' && s[k+2] == 'f') { 75 cnt++; 76 break; 77 } else if (s[k] =='f' && s[k+1] == 'f' && s[k+2] == 'f') { 78 cnt++; 79 break; 80 } 81 } 82 tot++; 83 } 84 cout << i << ' ' << p-cnt << endl; 85 } 86 } 87 /* 88 f_i = f_{i-1} + f_{i-3} +f_{i-4}; 89 1 0 1 1 90 1 0 0 0 91 0 1 0 0 92 0 0 1 0 93 */ 94 int main() { 95 ios_base::sync_with_stdio(0); 96 cin.tie(0); 97 db(); 98 99 a.p[0][0] = 9; 100 a.p[1][0] = 6; 101 a.p[2][0] = 4; 102 a.p[3][0] = 2; 103 b.p[0][0] = 1; 104 b.p[0][2] = 1; 105 b.p[0][3] = 1; 106 b.p[1][0] = 1; 107 b.p[2][1] = 1; 108 b.p[3][2] = 1; 109 while (cin >> n >> mod) { 110 cout << solve() << endl; 111 } 112 return 0; 113 }