[ARC168C] Swap Characters 题解
[ARC168C] Swap Characters 题解
来一篇代码可读性较好的题解。
题意
给你一个长度为 ABC
。定义一次操作:在
对
思路
注意到与答案有关的只是 A
、B
、C
的个数。
- 枚举
A
与B
交换的次数 。 - 枚举
A
与C
交换的次数 。 - 枚举
B
与C
交换的次数 。 - 枚举轮换
ABC
的次数 。 - 用多重组合数直接计算即可。
注意轮换有两种:ABC -> BCA
与 ABC -> CAB
。对于
时间复杂度
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 250000 + 5;
const ll MOD = 998244353;
ll n, m;
ll a, b, c;
ll fac[MAXN], invfac[MAXN], inv[MAXN];
void init(ll n) {
fac[0] = 1; fac[1] = 1;
invfac[0] = 1; invfac[1] = 1;
inv[1] = 1;
for (ll i = 2; i <= n; i++) {
fac[i] = fac[i-1] * i % MOD;
inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
invfac[i] = invfac[i-1] * inv[i] % MOD;
}
}
ll C(ll n, ll a, ll b, ll c) { // 多重组合数
if (a < 0 || b < 0 || c < 0) return 0;
return fac[n] * invfac[a] % MOD * invfac[b] % MOD * invfac[c] % MOD;
}
int main() { ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m; init(250000);
for (int i = 1; i <= n; i++) {
char ch; cin >> ch;
if (ch == 'A') a++;
else if (ch == 'B') b++;
else if (ch == 'C') c++;
}
ll ans = 0;
for (ll i = 0; i <= m; i++) // AB 交换的次数
for (ll j = 0; i + j <= m; j++) // AC 交换的次数
for (ll k = 0; i + j + k <= m; k++) // BC 交换的次数
for (ll t = 0; i + j + k + t * 2 <= m; t++) { // ABC 轮换的次数
ll prod1
= C(a, a-i-j-t, i, j+t)
* C(b, i+t, b-i-k-t, k) % MOD
* C(c, j, k+t, c-j-k-t) % MOD;
ll prod2
= C(a, a-i-j-t, i+t, j)
* C(b, i, b-i-k-t, k+t) % MOD
* C(c, j+t, k, c-j-k-t) % MOD;
if (t)
(ans += prod1 + prod2) %= MOD;
else
(ans += prod1) %= MOD;
}
cout << ans << '\n';
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧