http://acm.hdu.edu.cn/showproblem.php?pid=2604
题意:
有 l 个人 排成一队,这l 个人可以 f(女人),也可能是 m(男人),求 这些人中 不含有 fmf 和 fff 这样的子序列的 个数.
结果 % mod
输入 l, mod;
题解:
由于L 比较大 ,我们可以求出 递推式后 用矩阵 乘法 求结果。
接下来我们要考虑递推到n时新生成的E-queues,显然只考虑n-1时E-queues的最后两位的情况即可
我们用 an 表示 以 开头为 fm 的数量 ,bn 表示 开头为 ff的数量 ,cn 表示 开头为 mf 的数量 dn 表示 开头为 mm 的数量。
则
an = d(n-1);
bn = a(n - 1);
cn = a(n - 1) + b(n - 1);
dn = c(n - 1) + d(n - 1);
最后 求 an+bn+cn+dn 即可
an 0 0 0 1 a(n -1)
bn = 1 0 0 0 * b(n - 1)
cn 1 0 1 0 c(n - 1)
dn 0 0 1 1 d(n - 1)
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include< set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include< string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-12
15 #define inf 100000000
16 #define mx 1<<60
17 #define ll __int64
18 const double pi = acos(- 1.0);
19 const int maxn = 200;
20 using namespace std;
21 struct matrix
22 {
23 int m[ 4][ 4];
24 }p,b,e;
25 int mod;
26 void init()
27 {
28 CL(p.m, 0);
29 p.m[ 0][ 3] = 1;
30 p.m[ 1][ 0] = 1;
31 p.m[ 2][ 0] = 1;
32 p.m[ 2][ 1] = 1;
33 p.m[ 3][ 2] = 1;
34 p.m[ 3][ 3] = 1;
35
36 CL(b.m, 0);
37 b.m[ 0][ 0] = 1;
38 b.m[ 1][ 0] = 1;
39 b.m[ 2][ 0] = 1;
40 b.m[ 3][ 0] = 1;
41
42 for( int i = 0 ; i < 4;i++)
43 {
44 e.m[i][i] = 1;
45 }
46
47 }
48 matrix mtmul(matrix a,matrix b)
49 {
50 int i,j,k;
51 matrix c;
52 CL(c.m, 0);
53 for(i = 0 ; i < 4;i++)
54 {
55 for(k = 0; k < 4;k++)
56 {
57
58 if(a.m[i][k])
59 for(j = 0 ; j < 4;j++)
60 {
61 c.m[i][j] += a.m[i][k]*b.m[k][j];
62 c.m[i][j]%=mod;
63
64 }
65 }
66 }
67 return c;
68 }
69 matrix mtpow(matrix d, int k)
70 {
71 matrix a;
72 if(k == 1) return d;
73 int mid = k / 2;
74 a = mtpow(d,k/ 2);
75 a = mtmul(a,a);
76 if(k & 1)
77 {
78 a = mtmul(a,d);
79 }
80 return a;
81
82
83 }
84 int main()
85 {
86 int len,i;
87
88 while(scanf( " %d%d ",&len,&mod)!=EOF)
89 {
90
91 init() ;
92 if(len == 1)
93 {
94 printf( " %d\n ", 2 % mod);
95
96 continue ;
97 }
98 if(len == 2)
99 {
100 printf( " %d\n ", 4 % mod);
101 continue ;
102 }
103
104
105 matrix d ;
106 d = mtpow(p,len - 2);
107
108
109 d = mtmul(d,b);
110 int ans = 0;
111 for(i = 0 ; i < 4;i++)
112 {
113 ans += d.m[i][ 0];
114 ans %= mod;
115 }
116 printf( " %d\n ",ans);
117 }
118 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include< set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include< string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-12
15 #define inf 100000000
16 #define mx 1<<60
17 #define ll __int64
18 const double pi = acos(- 1.0);
19 const int maxn = 200;
20 using namespace std;
21 struct matrix
22 {
23 int m[ 4][ 4];
24 }p,b,e;
25 int mod;
26 void init()
27 {
28 CL(p.m, 0);
29 p.m[ 0][ 3] = 1;
30 p.m[ 1][ 0] = 1;
31 p.m[ 2][ 0] = 1;
32 p.m[ 2][ 1] = 1;
33 p.m[ 3][ 2] = 1;
34 p.m[ 3][ 3] = 1;
35
36 CL(b.m, 0);
37 b.m[ 0][ 0] = 1;
38 b.m[ 1][ 0] = 1;
39 b.m[ 2][ 0] = 1;
40 b.m[ 3][ 0] = 1;
41
42 for( int i = 0 ; i < 4;i++)
43 {
44 e.m[i][i] = 1;
45 }
46
47 }
48 matrix mtmul(matrix a,matrix b)
49 {
50 int i,j,k;
51 matrix c;
52 CL(c.m, 0);
53 for(i = 0 ; i < 4;i++)
54 {
55 for(k = 0; k < 4;k++)
56 {
57
58 if(a.m[i][k])
59 for(j = 0 ; j < 4;j++)
60 {
61 c.m[i][j] += a.m[i][k]*b.m[k][j];
62 c.m[i][j]%=mod;
63
64 }
65 }
66 }
67 return c;
68 }
69 matrix mtpow(matrix d, int k)
70 {
71 matrix a;
72 if(k == 1) return d;
73 int mid = k / 2;
74 a = mtpow(d,k/ 2);
75 a = mtmul(a,a);
76 if(k & 1)
77 {
78 a = mtmul(a,d);
79 }
80 return a;
81
82
83 }
84 int main()
85 {
86 int len,i;
87
88 while(scanf( " %d%d ",&len,&mod)!=EOF)
89 {
90
91 init() ;
92 if(len == 1)
93 {
94 printf( " %d\n ", 2 % mod);
95
96 continue ;
97 }
98 if(len == 2)
99 {
100 printf( " %d\n ", 4 % mod);
101 continue ;
102 }
103
104
105 matrix d ;
106 d = mtpow(p,len - 2);
107
108
109 d = mtmul(d,b);
110 int ans = 0;
111 for(i = 0 ; i < 4;i++)
112 {
113 ans += d.m[i][ 0];
114 ans %= mod;
115 }
116 printf( " %d\n ",ans);
117 }
118 }