1. 题目解析与核心思路这道题目来自AtCoder Grand Contest 040编号为C题。题目要求我们统计所有长度为NN为偶数的由A、B、C组成的字符串中能够通过特定删除操作变为空串的数量。具体来说每次操作可以选择删除任意两个连续的字符但不能删除AB或BA这两种组合。1.1 问题转化技巧直接处理不能删除AB或BA的条件比较困难这里有一个巧妙的转化思路将字符串中偶数位置的所有A和B互换。具体来说对于原字符串s构造新字符串s其中s[i] s[i]当i为奇数s[i] B当s[i]A且i为偶数s[i] A当s[i]B且i为偶数s[i] C当s[i]C且i为偶数经过这样的变换后原问题中的限制条件不能删除AB或BA就变成了不能删除AA或BB。这是因为原字符串中的AB或BA组合在变换后会变成AA或BB其他组合如AC、BC等则保持原有性质或变成其他允许的组合这个转化是一一对应的因此我们可以转而计算变换后字符串中满足不能删除AA或BB条件的数量。1.2 关键观察与条件分析经过上述转化后我们需要计算的是在变换后的字符串中能够通过不断删除非AA且非BB的两个连续字符最终将字符串清空的数量。这里有一个重要的观察一个字符串不能被完全删除当且仅当其中A的数量或B的数量超过字符串长度的一半即≥N/2。这是因为如果A的数量≥N/2那么至少有两个A会相邻根据鸽巢原理形成不能删除的AA组合同理如果B的数量≥N/2也会形成不能删除的BB组合只有当A和B的数量都严格小于N/2时才能保证总能找到可删除的字符对因此我们可以用总字符串数减去不满足条件的字符串数来得到答案。2. 组合数学解法详解2.1 总体思路与公式推导设N为偶数总共有3^N个可能的字符串每个位置有3种选择。我们需要从中减去那些A的数量≥N/2或B的数量≥N/2的字符串。根据容斥原理非法字符串的数量为 非法数量 (A≥N/2的数量) (B≥N/2的数量) - (A≥N/2且B≥N/2的数量)由于A和B的数量不可能同时≥N/2因为AB≤N而N/2N/2N此时C的数量必须为0所以最后一项为0。因此非法数量 (A≥N/2的数量) (B≥N/2的数量)由于A和B的情况对称我们只需要计算其中一种然后乘以2即可。2.2 组合数计算对于A的数量≥N/2的情况我们可以枚举A的数量k从N/21到N然后计算对应的字符串数量对于固定的kA的数量剩余N-k个位置可以是B或C每个有2种选择。因此数量为C(N,k) * 2^{N-k}其中C(N,k)是组合数表示从N个位置中选择k个位置放A。因此总非法数量为 sum 2 * Σ_{kN/21}^N C(N,k) * 2^{N-k}最终答案为 ans 3^N - sum2.3 模运算处理由于N可以达到1e7结果需要对998244353取模我们需要高效计算组合数和幂次。3. 算法实现与优化3.1 预处理阶乘和逆元为了高效计算组合数C(N,k) N! / (k! * (N-k)! ) mod 998244353我们需要预处理阶乘数组mul[i] i! mod 998244353阶乘的逆元数组inv[i] (i!)^-1 mod 998244353计算逆元可以使用费马小定理因为998244353是质数 a^{-1} ≡ a^{mod-2} mod mod3.2 快速幂实现我们需要实现快速幂函数来计算幂次和逆元long long q_pow(long long u, long long v) { long long res 1ll; while(v) { if(v 1ll) res res * u % mod; u u * u % mod; v 1; } return res; }3.3 组合数计算函数预处理阶乘和逆元后组合数可以O(1)计算long long C(int u, int v) { return mul[u] * inv[v] % mod * inv[u - v] % mod; }3.4 主算法流程预处理阶乘、逆元和2的幂次计算总字符串数3^N mod 998244353计算非法字符串数量sum输出(3^N - 2*sum) mod 9982443534. 完整代码解析#include bits/stdc.h using namespace std; const int N 10000010; const long long mod 998244353ll; int n; long long mul[N 10], inv[N 10], pow2[N 10]; // 快速幂函数 long long q_pow(long long u, long long v) { long long res 1ll; while(v) { if(v 1ll) res res * u % mod; u u * u % mod; v 1; } return res; } // 预处理阶乘、逆元和2的幂次 void init() { mul[0] inv[0] pow2[0] 1ll; for(int i 1; i N; i) { mul[i] mul[i - 1] * (long long)i % mod; pow2[i] pow2[i - 1] * 2ll % mod; } inv[N] q_pow(mul[N], mod - 2ll); for(int i N - 1; i 0; --i) { inv[i] inv[i 1] * (long long)(i 1) % mod; } } // 组合数计算 long long C(int u, int v) { return mul[u] * inv[v] % mod * inv[u - v] % mod; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin n; init(); long long ans q_pow(3ll, n), sum 0ll; // 计算非法情况总和 for(int i n / 2 1; i n; i) { sum (sum C(n, i) * pow2[n - i] % mod) % mod; } // 最终答案 cout (ans - 2ll * sum % mod mod) % mod; return 0; }5. 复杂度分析与优化5.1 时间复杂度预处理阶乘、逆元和2的幂次O(N)计算3^NO(log N)快速幂计算sumO(N/2) ≈ O(N)总时间复杂度O(N)5.2 空间复杂度需要存储阶乘、逆元和2的幂次数组每个大小都是N1因此空间复杂度为O(N)5.3 优化技巧预处理范围只需要到N不需要到1e7可以边计算阶乘边计算2的幂次减少循环次数逆元计算可以从N倒推利用inv[i] inv[i1] * (i1) % mod6. 常见问题与调试技巧6.1 模运算注意事项减法取模(a - b) % mod 可能为负数需要加上mod再取模乘法取模两个1e9级别的数相乘可能溢出long long建议使用快速乘或先取模除法取模必须转换为乘以逆元6.2 边界条件处理N0时空字符串视为合法应返回1N2时只有AA和BB非法应返回3^2 - 2*1 7需要验证N的奇偶性题目保证N为偶数6.3 调试技巧对小数据手工计算验证打印中间结果如阶乘、逆元值检查是否正确使用assert验证关键条件如组合数性质7. 算法扩展与变种7.1 奇数长度的情况如果N为奇数问题会变得复杂因为最后会剩下一个字符。需要考虑最终剩余字符的限制条件。7.2 更多字符限制如果字符集扩大如加入D、E等或者禁止删除的组合增多可能需要更复杂的容斥原理应用。7.3 不同删除规则如果删除规则变化如可以删除任意长度的子串或者有更多限制条件可能需要完全不同的解法如动态规划。在实际编程比赛中遇到这类问题时关键在于发现问题的对称性和可转化性。这道题的巧妙之处在于通过字符位置的变换将复杂条件简化为更易处理的形式。对于类似的字符串操作问题尝试寻找不变量或进行恰当的转化往往是解题的关键。
企业数字化 ERP 产品动态
相关推荐
vcruntime140_1.dll缺失深度解析:VC++运行库修复与系统依赖问题解决指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/23 7:26:41
AI原生开发实战:从意图规格到验证流水线的完整指南 1. 从一份内部手册说起:AI 原生开发到底在解决什么问题第一次看到“AI 原生软件开发手册”这个说法,我脑子里冒出来的第一个念头是:又一个新瓶装旧酒的概念?毕竟这些年从敏捷到 DevOps 再到平台工程,每一波都号称要颠覆… · 2026/9/23 7:26:41
SpringBoot+Vue校园资料分享平台开发实践 1. 项目背景与核心价值校园资料分享平台是近年来高校信息化建设中需求迫切的实用型项目。作为计算机相关专业毕业设计的选题,它完美融合了技术实践与校园场景需求,既能展示学生全栈开发能力,又具备实际应用价值。我指导过的3届毕业生中&#… · 2026/9/23 7:26:41
三星手机数据彻底清除方法与安全指南 1. 三星手机数据彻底清除的必要性作为全球市场份额前三的手机品牌,三星设备承载着大量用户的个人隐私和敏感数据。根据2023年移动安全报告显示,超过67%的二手手机交易存在数据泄露风险。我在手机维修店工作期间,就遇到过不少因为转卖旧手机导… · 2026/9/23 10:35:58
淘宝怎么开通直播速查手册:3个坑让性能提升5倍 淘宝怎么开通直播速查手册:3个坑让性能提升5倍 刚把直播推流服务部署上去,控制台疯狂报 502 Bad Gateway ,视频卡顿得像PPT,观众骂声一片。你手里拿着复制来的开源代码,改了一宿参数,还是跑不通,根本不知道哪个环节在拖后腿。这… · 2026/9/23 10:35:58
爱奇艺播放失败图解原理:3步定位卡顿根源 爱奇艺播放失败图解原理:3步定位卡顿根源 看着屏幕上一片雪花,耳边传来“缓冲中”的提示,心里是不是在滴血?打开控制台,满屏红色的 Uncaught TypeError 和长长的 StackTrace… · 2026/9/23 10:35:51
IP欺骗源码解析:3个坑让运维崩溃,附实战代码 IP欺骗源码解析:3个坑让运维崩溃,附实战代码 版本升级后 API 全变了?昨天还跑通的 IP 校验脚本,今天突然全报“非法请求”。别慌,这不是玄学,是 IP欺骗(IP Spoofing) 攻击在搞鬼,而你的代码没做防御。我翻了 3… · 2026/9/23 10:35:51
python+pygame实现扫雷游戏之三 我们已经实现了:
pythonpygame实现扫雷游戏之一
pythonpygame实现扫雷游戏之二
下面就可以实例化MineBlock及响应鼠标消息循环了。其本质就是不停地接收鼠标事件,改变二维数组的状态,然后“画”在屏幕上就可以了。
六、
main.py
# -*- … · 2026/9/23 10:35:51
公考高频成语解析:安之若素的正确用法与答题技巧 1. 成语解析:安之若素的核心要义"安之若素"这个成语在公考行测中出现的频率相当高,但很多考生往往只记住了表面意思,在实际做题时却容易混淆。我们先从最基础的层面来拆解这个成语。1.1 字面拆解与读音要点这个成语的正确读音是&qu… · 2026/9/23 10:35:45
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29