[ABC271G] Access Counter 题解
[ABC271G] Access Counter 题解
思路
挺难的 DP。
状态里面不能含有天数,只能从时间点入手,一眼矩阵快速幂所以考虑以登录次数作为阶段设计状态。
可以得到这个DP:
转移可以考虑枚举上一个登录的时间点,注意到上一次登录可能在几天前,所以令
考虑求
然后矩阵快速幂优化
时间复杂度:
// Problem: [ABC271G] Access Counter
// Contest: Luogu
// Author: Moyou
// Copyright (c) 2023 Moyou All rights reserved.
// Date: 2024-01-02 22:24:40
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 25, mod = 998244353;
struct Mat {
int m[N][N], r, c;
void clear(int R, int C) {
memset(m, 0, sizeof m);
r = R, c = C;
}
void init() {
for (int i = 1; i <= min(r, c); i++)
m[i][i] = 1;
}
friend Mat operator*(const Mat a, const Mat b) {
Mat res; res.clear(a.r, b.c);
for (int k = 1; k <= a.c; k++)
for (int i = 1; i <= a.r; i++)
for (int j = 1; j <= b.c; j++)
res.m[i][j] = (res.m[i][j] + 1ll * a.m[i][k] * b.m[k][j] % mod) % mod;
return res;
}
void print() {
for(int i = 1; i <= r; i ++, cout << endl)
for(int j = 1; j <= c; j ++)
cout << m[i][j] << ' ';
}
} M, A;
Mat qmi(Mat a, ll b) {
Mat res; res.clear(a.r, a.c), res.init();
while(b) {
if(b & 1) res = res * a;
b >>= 1;
a = a * a;
}
return res;
}
int qmi(int a, ll b) {
int res = 1;
while(b) {
if(b & 1) res = 1ll * res * a % mod;
b >>= 1, a = 1ll * a * a % mod;
}
return res;
}
ll n;
int px, py, p[N], w[N][N], pall;
string s;
int f(int i, int j) {
return 1ll * w[i][j] * p[j] % mod * qmi((1ll - pall + mod) % mod, mod - 2) % mod;
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> px >> py >> s;
pall = 1;
px = 1ll * px * qmi(100, mod - 2) % mod, py = 1ll * py * qmi(100, mod - 2) % mod;
for(int i = 1; i <= 24; i ++) {
p[i] = (s[i - 1] == 'T' ? px : py);
pall = 1ll * pall * (1ll - p[i]) % mod;
}
for(int i = 1; i <= 24; i ++) {
for(int j = 1; j <= 24; j ++) {
int tmp = 1;
for(int k = i % 24 + 1; k != j; k = k % 24 + 1) tmp = 1ll * tmp * (1ll - p[k]) % mod;
w[i][j] = tmp;
}
}
M.clear(24, 24), A.clear(24, 1);
for(int i = 1; i <= 24; i ++)
for(int j = 1; j <= 24; j ++)
M.m[i][j] = f(j, i);
A.m[24][1] = 1;
A = qmi(M, n) * A;
int ans = 0;
for(int i = 1; i <= 24; i ++)
if(s[i - 1] == 'A') ans = (1ll * ans + A.m[i][1]) % mod;
cout << (ans + mod) % mod << '\n';
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2023-01-02 [NOI2018] 归程 题解