[ARC 188A] ABC Symmetry

news/2025/1/18 17:44:31/文章来源:https://www.cnblogs.com/keysky/p/18678649

solution by XiangXunYi

思路推导

step 1

首先题目中操作二同时删掉 ABC 的条件相当于同时将三者数量减一,操作一删掉两个相同字符等同于将某一字符的数量减二,那么我们可以发现只使用操作一不会改变奇偶,操作二则是同时反转奇偶,所以一个字符串是个好字符串的必要条件是其中三个字母数量的奇偶性相同,同时容易构造出一组解使其变为空字符串,故也是必要条件。
构造解:执行操作一直到不能执行为止,最后视情况执行操作二。

step2

由于题目的抽象数据范围较小且对于问号的抉择相互影响较大,联想到 dp。首先会想到把 \(K\) 放入 dp 状态中来 check 是否合法,但我们发现每次新增一个字符时算贡献是需要枚举之前前缀三个字符的奇偶性,但上一个状态又并不完全由所枚举的单个状态转移过来,dp 的转移就很扑朔迷离(至少我是这样)。所以要改变 dp 的定义,但又要计算好子段个数,所以状态必须能计算 \(K\) 值。

step 3

设一段区间 A 的数量对 \(2\) 取模为 \(a\)B 的数量对 \(2\) 取模为 \(b\)C 的数量对 \(2\) 取模为 \(c\)
因为好字段必须要三个字符数量奇偶性相同,抽象的理解为 \(0/1\) 状态,即区间和为 \(0\),前缀和呀!只要两点的前缀和值相等,这个区间就是一个好子段。我们设计一个 dp 状态 \(dp_{i,j,k,l,0/1/2/3}\) 表示存在 \(i\) 个位置前缀区间满足情况 \(0\)[1]\(j\) 个位置前缀区间满足情况 \(1\)[2]\(k\) 个位置前缀区间满足情况 \(2\)[3]\(l\) 个位置前缀区间满足情况 \(3\)[4]且上一个位置前缀区间满足情况 \(0/1/2/3\) 的方案数。
在这种 dp 状态的设计下,我们可以发现,四种情况不重不漏的涵盖了所有区间,当一个区间满足右端点和左端点减一是同一种情况就是一个好子段,最后好子段的个数就是 \(\frac{i \times (i + 1) + j \times (j - 1) + k \times (k - 1) + l \times (l - 1)}{2}\) 答案即为所有该值大于 \(K\)\(dp_{i,j,k,l,0/1/2/3}\) 累加起来。

step 4

定义有了,该题的转移并不难想,只要根据上一个位置的状态加上当前位置的字符即可转移(给个建议:用刷表)。

solution

定义 \(dp_{i,j,k,l,lst \in \{0/1/2/3\}}\) 表示有 \(i\) 个前缀满足情况 \(0\)\(j\) 个前缀满足情况 \(1\)\(k\) 个前缀满足情况 \(2\)\(l\) 个前缀满足情况 \(3\),上一个前缀的情况为 \(lst\)
对于当前字符为 A 时,情况 \(0\) 与情况 \(3\) 互换,情况 \(1\) 与情况 \(2\) 互换。
对于当前字符为 B 时,情况 \(0\) 与情况 \(1\) 互换,情况 \(2\) 与情况 \(3\) 互换。
对于当前字符为 C 时,情况 \(0\) 与情况 \(2\) 互换,情况 \(1\) 与情况 \(3\) 互换。

int pos = i + j + k + l;
int tmp[4] = { i, j, k, l };
int x = lst ^ 3, y = lst ^ 1, z = lst ^ 2;
if ((s[pos] == '?' || s[pos] == 'A') && tmp[x] + 1 <= n) {tmp[x]++;trans(dp[tmp[0]][tmp[1]][tmp[2]][tmp[3]][x] , dp[i][j][k][l][lst]);tmp[x]--;
}
if ((s[pos] == '?' || s[pos] == 'B') && tmp[y] + 1 <= n) {tmp[y]++;trans(dp[tmp[0]][tmp[1]][tmp[2]][tmp[3]][y] ,dp[i][j][k][l][lst]);tmp[y]--;
}
if ((s[pos] == '?' || s[pos] == 'C') && tmp[z] + 1 <= n) {tmp[z]++;trans(dp[tmp[0]][tmp[1]][tmp[2]][tmp[3]][z] , dp[i][j][k][l][lst]);tmp[z]--;
}

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 55;
const int mod = 998244353;
int n, least, dp[N][N][N][N][4];
char s[55];
inline void trans(int& x, int y) { x = (x + y) % mod; }
int main() {scanf("%d%d%s", &n, &least, s);dp[0][0][0][0][0] = 1;for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)for (int k = 0; k < n; ++k)for (int l = 0; l < n; ++l)if (i + j + k + l < n)for (int lst = 0; lst < 4; ++lst) {int pos = i + j + k + l;int tmp[4] = { i, j, k, l };int x = lst ^ 3, y = lst ^ 1, z = lst ^ 2;if ((s[pos] == '?' || s[pos] == 'A') && tmp[x] + 1 <= n) {tmp[x]++;trans(dp[tmp[0]][tmp[1]][tmp[2]][tmp[3]][x] , dp[i][j][k][l][lst]);tmp[x]--;}if ((s[pos] == '?' || s[pos] == 'B') && tmp[y] + 1 <= n) {tmp[y]++;trans(dp[tmp[0]][tmp[1]][tmp[2]][tmp[3]][y] ,dp[i][j][k][l][lst]);tmp[y]--;}if ((s[pos] == '?' || s[pos] == 'C') && tmp[z] + 1 <= n) {tmp[z]++;trans(dp[tmp[0]][tmp[1]][tmp[2]][tmp[3]][z] , dp[i][j][k][l][lst]);tmp[z]--;}}int ans = 0;for (int i = 0; i <= n; ++i)for (int j = 0; j <= n; ++j)for (int k = 0; k <= n; ++k)for (int l = 0; l <= n; ++l)for (int lst = 0; lst < 4; ++lst)if (i + j + k + l == n && i * (i + 1) + j * (j - 1) + k * (k - 1) + l * (l - 1) >> 1 >= least)trans(ans, dp[i][j][k][l][lst]);printf("%d\n", ans);return 0;
}

  1. \(a = b \ and \ a = c\) ↩︎

  2. \(a = c \ and \ a \neq b\) ↩︎

  3. \(a = b \ and \ a \neq c\) ↩︎

  4. \(a \neq b \ and \ b = c\) ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/871323.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「NOIP2024」 树上查询

update 2024/12/28 题目描述 给定一棵树,每次询问区间 \([l,r]\) 的 \[\max_{l \le l \le r \le r \land r - l + 1 \ge k}\text{dep}_ {\text{LCA*}(l, r)} \]引理证明 先来证两个区间 \(\text{LCA}\) 的引理: 对于 \(\text{LCA} \{ l, l + 1, \dots r\}\) 我们有 \(\text{L…

Flask Web开发实战:入门、进阶与原理解析PDF免费下载

PythonWeb框架Flask开发团队成员撰写,内容全面,从基础知识到进阶实战,再到源码分析,提供完善的Flask学习路径适读人群 :本书适合了解Python基本语法,想要自己动手做网站的编程人员;熟悉Python。想要从事Python Web开发的后端工程师、运维工程师和爬虫工程师;香葱Django…

CMU 15-445 23Fall总结

注:编译、测试之前运行sudo sysctl vm.mmap_rnd_bits=28 BusTubs architecture: 1. Query Processing (查询处理层) 负责将输入的 SQL 查询转化为可执行的物理查询计划。Parser(解析器):将输入的 SQL 字符串解析为抽象语法树 (AST),检查 SQL 语法是否合法。 Binder(绑定器…

从数据到模型,足球预测方法解析

在足球赛事范畴内,比赛结局始终蕴含着诸多不确定性,而这恰恰构成了足球独特的魅力要素。对于广大球迷而言,尝试预测足球比赛的最终结果,向来是一项极具吸引力与挑战性的活动。 近年来,伴随数据科学以及机器学习技术的迅猛发展,足球预测领域发生了深刻变革。这些先进技术为…

传奇三虚拟机服务端-客户端win10可用

论坛转来的,还没有实验架设 传奇3 虚拟机服务端一键架设。。。好吧,三键架设,据说WIN10可玩服务端启动稍微有点步骤,还算简单吧QQ截图20200414142743.jpg (73.53 KB, 下载次数: 0)下载附件2020-4-14 14:41 上传QQ截图20200414142828.jpg (74.73 KB, 下载次数: 0)下载附件20…

THREE.js学习笔记9——Materials

这一小节主要学习材质 材质用于为几何物理模型的每个可见像素添加颜色。 Materials are used to put a color on each visible pixel of the geometries. 决定每个像素颜色的算法是在程序中编写的,称为着色器。 Three.js 具有许多带有预制着色器的内置材料。 Algorithms that …

[HarekazeCTF2019]baby_rop2(read的libc)

一个normal的栈溢出,没有system和binsh,为ret2libc 这里也没有常见的write和puts,所以我们用read泄露libc基址,并使用printf打印read的地址 这里注意printf的第一个参数必须是格式字符串,即Welcome to the Pwn World again(地址为0x0400770,第二个参数设为read_got(got表…

Living-Dream 系列笔记 第93期

最大流 EK & Dinic本文讲解 EK & Dinic 算法。 最大流 最大流的模型:特别注意:这个流量上限不是单次流量不超过它,而是多次的总和不超过它。 EK 显然这个问题是可以使用 dfs 解决的,但是效率低下。 考虑如下的图。我们发现 dfs 有可能走了 \(S \to A \to B \to T\)…

【每日一题】20250118

我是时间唯一的主人。成为自己的时间的主人是一种奢侈。我认为这是人类能够送给自己的最奢侈的东西之一。【每日一题】 1.(16分) \(\hspace{0.6cm}\)如图所示,在以坐标原点 \(O\) 为圆心、半径为 \(R\) 的半圆形区域内,有相互垂直的匀强电场和匀强磁场,磁感应强度为 \(B\),…

思通数科舆情监测系统:精准实现数据监测与实时预警的应用意义

随着信息化社会的深入发展,舆情管理变得愈加复杂,尤其是在社交媒体和网络平台的广泛应用下,信息传播的速度与影响力呈现出指数级增长。如何高效监测和分析这些海量数据,成为各级政府、企业和公共机构亟待解决的问题。思通数科的舆情监测系统,凭借强大的数据监控与分析能力…

中考英语优秀范文-热点话题-传统文化-009 Dragon Boat Festival 端午节

1 写作要求 为弘扬中华传统文化,增强文化自觉,学校将举行一次英语演讲比赛。请以“ ___________Festival”为题,写一篇演讲稿,介绍一个你最喜欢的中国传统节日。 提示问题: What is your favorite traditional festival? Can you say some basic facts about it? How do…

在线json调试工具

在线json格式化工具,无需登录,打开即用 https://json.openai2025.com/