每天存在 A
和 T
组成的长度为 T
则 Taka 有 A
则 Aoki 有
首先看一眼这个题面与
一个显而易见但较为重要的性质,即两次访问之间间隔的天数是易于统计的,重要的在于两次访问的时间点
令对应时间点的访问成功概率为
显然和式为等比数列求和,且由题意可知公比
显然
于是我们完成了
令
按照我们之前的想法挂到矩阵上:
显然
答案统计一下所有
xxxxxxxxxx
1441
2
3
4
5
6
7
8
9
10
11
12using namespace std;
13
14mt19937 rnd(random_device{}());
15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
16bool rnddd(int x){return rndd(1, 100) <= x;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21typedef long double ld;
22
23
24
25template < typename T = int >
26inline T read(void);
27
28ll N;
29ll Taka, Aoki;
30ll p[30];
31ll P(1);
32ll ansv(0);
33ll inv100;
34ll dp[30][30];
35bitset < 30 > belong;
36
37ll qpow(ll a, ll b){
38 ll ret(1), mul(a);
39 while(b){
40 if(b & 1)ret = ret * mul % MOD;
41 b >>= 1;
42 mul = mul * mul % MOD;
43 }return ret;
44}
45
46class Matrix{
47private:
48 int siz;
49 ll v[30][30];
50public:
51 Matrix(int len = 24, int pat = 0){
52 siz = len;
53 for(int i = 0; i < siz; ++i)
54 for(int j = 0; j < siz; ++j)
55 v[i][j] = 0;
56 switch(pat){
57 case 1:{
58 for(int i = 0; i < siz; ++i)v[i][i] = 1;
59 break;
60 }
61 case 2:{
62 v[0][siz - 1] = 1;
63 break;
64 }
65 case 3:{
66 for(int i = 1; i <= siz; ++i)
67 for(int j = 1; j <= siz; ++j)
68 v[i - 1][j - 1] = dp[i][j];
69 break;
70 }
71 default: break;
72 }
73 }
74 friend Matrix operator * (const Matrix &a, const Matrix &b){
75 Matrix ret(24);
76 for(int i = 0; i < 24; ++i)
77 for(int j = 0; j < 24; ++j)
78 for(int k = 0; k < 24; ++k)
79 (ret.v[i][j] += a.v[i][k] * b.v[k][j] % MOD) %= MOD;
80 return ret;
81 }
82 void SetAns(void){
83 for(int i = 0; i < 24; ++i)
84 if(belong[i + 1])(ansv += v[0][i]) %= MOD;
85 }
86 void Print(void){
87 printf("##########\n");
88 for(int i = 0; i < siz; ++i)
89 for(int j = 0; j < siz; ++j)
90 printf("%lld%c", v[i][j], j == siz - 1 ? '\n' : ' ');
91 printf("##########\n");
92 }
93}ans(24, 2);
94
95Matrix qpow(Matrix a, ll b){
96 Matrix ret(24, 1), mul(a);
97 while(b){
98 if(b & 1)ret = ret * mul;
99 b >>= 1;
100 mul = mul * mul;
101 }return ret;
102}
103
104int main(){
105 inv100 = qpow(100, MOD - 2);
106 N = read < ll >(), Taka = read(), Aoki = read();
107 for(int i = 1; i <= 24; ++i){
108 char c = getchar(); while(!isalpha(c))c = getchar();
109 p[i] = c == 'T' ? Taka : Aoki, belong[i] = c == 'T' ? false : true;
110 (P *= (100 - p[i]) * inv100 % MOD) %= MOD;
111 }
112 for(int i = 1; i <= 24; ++i){
113 for(int j = 1; j <= 24; ++j){
114 ll R(1);
115 if(i < j)for(int k = i + 1; k <= j - 1; ++k)(R *= (100 - p[k]) * inv100 % MOD) %= MOD;
116 else{
117 for(int k = i + 1; k <= 24; ++k)(R *= (100 - p[k]) * inv100 % MOD) %= MOD;
118 for(int k = 1; k <= j - 1; ++k)(R *= (100 - p[k]) * inv100 % MOD) %= MOD;
119 }
120 dp[i][j] = R * (p[j] * inv100 % MOD) % MOD * qpow((1 - P + MOD) % MOD, MOD - 2) % MOD;
121 }
122 }
123 Matrix base(24, 3);
124 (ans * qpow(base, N)).SetAns();
125 printf("%lld\n", ansv);
126 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
127 return 0;
128}
129
130template < typename T >
131inline T read(void){
132 T ret(0);
133 int flag(1);
134 char c = getchar();
135 while(c != '-' && !isdigit(c))c = getchar();
136 if(c == '-')flag = -1, c = getchar();
137 while(isdigit(c)){
138 ret *= 10;
139 ret += int(c - '0');
140 c = getchar();
141 }
142 ret *= flag;
143 return ret;
144}
update-2023_02_09 初稿