当前位置: 首页 > news >正文

题解:AtCoder AT_abc470_f Googol Swaps

【题目来源】

AtCoder:F - Googol Swaps

【题目描述】

You are given a string \(S\) of length \(N\) consisting of lowercase English letters.
Find the number, modulo \(998244353\), of strings that \(S\) can become after performing the following operation exactly \(10^{100}\) times.

  • Choose an integer \(i\) between \(1\) and \(M\), inclusive, and swap the \(A_i\)-th and \(B_i\)-th characters of \(S\).

给定一个长度为 \(N\)、由小写英文字母组成的字符串 \(S\)

求将以下操作恰好执行 \(10^{100}\) 次后,\(S\) 能变成的字符串数量,对 \(998244353\) 取模。

  • 选择 \(1\)\(M\) 之间(含)的整数 \(i\),并交换 \(S\) 的第 \(A_i\) 个字符和第 \(B_i\) 个字符。

【输入】

The input is given from Standard Input in the following format:

\(N\) \(M\)
\(S\)
\(A_1\) \(B_1\)
\(\vdots\)
\(A_M\) \(B_M\)

【输出】

Output the answer.

【输入样例】

5 3
miria
1 3
2 5
4 5

【输出样例】

6

【核心思想】

  1. 问题分析:给定字符串 \(S\)\(M\) 对可交换位置,求恰好执行 \(10^{100}\) 次交换后能得到的字符串数量(模 \(998244353\))。由于 \(10^{100}\) 是极大的偶数,核心观察是:交换操作生成一个置换群,恰好执行 \(10^{100}\) 次等价于在群中取 \(10^{100}\) 次幂。通过并查集找到交换操作生成的连通块,每个连通块内字符可任意重排,但偶数次操作限制了某些排列的可达性。

  2. 算法选择

    • 并查集:找到由交换操作连接的连通块,每个连通块内的位置可自由交换
    • 多重集排列:每个连通块内的字符串排列数为 \(\frac{siz!}{\prod cnt_c!}\)
    • 群论分析:若连通块内无重复字符,所有排列的阶为 \(2\)(交换生成对称群 \(S_{siz}\),但 \(10^{100}\) 为偶数,只有偶排列可达,方案数需除以 \(2\)
  3. 关键步骤

    • 初始化:读取 \(N\)\(M\)\(S\),并查集初始化
    • 建图合并:读入 \(M\) 对交换位置 \((A_i, B_i)\),用并查集合并
    • 预处理阶乘和逆元\(fac[i] = i! \bmod mod\)\(invfac[i] = (i!)^{-1} \bmod mod\)(费马小定理)
    • 按连通块分组:统计每个连通块包含的位置和字符频率
    • 计算答案
      • 对每个连通块,计算多重集排列数 \(ways = \frac{siz!}{\prod cnt_c!}\),累乘到 \(ans\)
      • 检查连通块内是否有重复字符:若有,\(flag = false\)(存在不动点,偶数次操作不影响计数)
      • 若所有连通块内字符均不重复(\(flag = true\)):\(ans = ans \times 2^{-1} \bmod mod\)(只有偶排列可达)
    • 输出答案 \(ans\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N \alpha(N) + N \log mod)\),并查集近乎线性,阶乘预处理和快速幂为 \(O(N \log mod)\)
    • 空间复杂度:\(O(N)\),并查集、阶乘数组、连通块分组
  5. 置换群与组合数学的核心思想

    • 连通块独立性:不同连通块的位置互不连通,字符无法跨块交换,总方案数为各连通块方案数的乘积
    • 多重集排列:连通块内字符可任意排列,但相同字符不可区分,用多重集排列公式计算
    • 偶数次操作的约束:当连通块内无重复字符时,交换操作生成完整的对称群,但 \(10^{100}\) 为偶数意味着只有偶排列(可分解为偶数个对换)可达,方案数减半
    • 有重复字符的特殊性:若连通块内有重复字符,存在非恒等排列在偶数次操作后仍可达(因交换相同字符不改变字符串),无需额外除法
    • 适用于置换群计数、组合数学、并查集连通性分析类问题

【算法标签】

排列组合

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long // 使用long long防止中间计算溢出
const int N = 200005, mod = 998244353; // N:最大字符串长度, mod:模数
int n, m; // n:字符串长度, m:可交换的位置对数
string s; // 原始字符串
int a[N], b[N]; // a[i]/b[i]:第i对可交换的位置(本题中未直接使用数组)
int p[N]; // 并查集父节点数组
int fac[N], invfac[N]; // fac:阶乘数组, invfac:阶乘逆元数组
map<int, vector<int>> groups; // 每个连通块包含的所有位置// 并查集查找:带路径压缩
int find(int x)
{if (p[x]!=x) p[x] = find(p[x]);return p[x];
}// 并查集合并
void merge(int a, int b)
{a = find(a), b = find(b);if (a != b)p[a] = b;
}// 快速幂:计算a^b % mod
int qmi(int a, int b)
{int res = 1;while (b){if (b&1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}signed main()
{cin >> n >> m >> s; // 读入字符串长度、交换对数和字符串s = " " + s; // 字符串下标从1开始// 初始化并查集for (int i=1; i<=n; i++)p[i] = i;// 读入m对可交换位置,并在并查集中合并for (int i=1; i<=m; i++){int a, b;cin >> a >> b;merge(a, b);}// 预处理阶乘数组fac[0] = 1;for (int i=1; i<=n; i++)fac[i] = fac[i-1] * i % mod;// 预处理阶乘逆元数组(费马小定理)invfac[n] = qmi(fac[n], mod-2);for (int i=n-1; i>=1; i--)invfac[i] = invfac[i+1] * (i+1) % mod;// 按连通块分组:每个根节点对应一个位置向量for (int i=1; i<=n; i++)groups[find(i)].push_back(i);int ans = 1; // 最终答案bool flag = true; // 标记是否所有连通块内字符都不重复// 遍历每个连通块,计算该连通块内的排列数for (auto t : groups){int root = t.first; // 连通块的根节点vector<int> vec = t.second; // 该连通块包含的所有位置int siz = vec.size(); // 连通块大小map<char, int> cnt; // 统计该连通块内每种字符的出现次数for (auto idx : vec)cnt[s[idx]]++;// 计算该连通块内的不同排列数:多重集排列公式 siz! / (c1! * c2! * ...)int ways = fac[siz];for (auto t : cnt){char c = t.first;int cnum = t.second;ways = ways * invfac[cnum] % mod;}ans = ans * ways % mod; // 各连通块独立,答案相乘// 检查该连通块内是否有重复字符bool hasDuplicate = false;for (auto t : cnt){char c = t.first;int cnum = t.second;if (cnum>=2){hasDuplicate = true;break;}}// 如果有重复字符,说明存在不动点(某些排列执行偶数次后回到原串)if (hasDuplicate)flag = false;}// 如果所有连通块内字符都不重复,则每个排列的阶都是2// 执行10^100次(偶数次)后,只有恒等排列能回到原串// 所以方案数需要除以2(乘以2的逆元)if (flag)ans = ans * qmi(2, mod-2) % mod;cout << ans << endl; // 输出最终答案return 0;
}

【运行结果】

5 3
miria
1 3
2 5
4 5
6
http://www.jsqmd.com/news/1376885/

相关文章:

  • 2026年苏州谷歌独立站推广专业机构选择指南 - GrowthUME
  • 2026杭州优质代理记账公司:数字化财税服务**与选型指南 - 品牌排行榜
  • 深圳市八匹马装饰工程有限公司:深耕工装领域的品质装修**企业 - GrowthUME
  • 2026年8月实力之选:无锡地区专业的知识产权管理体系认证咨询机构哪家好——无锡市中标管理咨询有限公司 - 网科
  • 大模型智能路由平台推荐怎么选?模型编排、成本治理与降级策略 - 小橘甄选
  • 信用代码证登报步骤与避坑要点,避免刊登无效无法补办证件 - 实用干货补给站
  • 单仁牛商玄琨GEO:生成式引擎优化(GEO)的核心原理与技术架构解析 - 汇聚至此
  • 全国东南亚留学通过率高:前沿趋势动态追踪整理 - 虚拟星辰
  • 高低温一体机选型指南,筛选口碑好、售后完善、综合实力突出的正规供应商 - 品牌推荐大师
  • 2026年8月济南机械革命电脑维修地址有哪些|10个区域到店核对与资料保护和硬盘状态核对 - 售后数码产品专业
  • 连锁门店弱电工程服务商,推荐小安派工,全国覆盖多省同步施工标准化交付全生命周期运维 - 小安派工
  • 选错geo服务商到底有多坑:服务商实力大盘点与选型决策参考 - 天下观知
  • 2026年8月南京机械革命授权售后办理步骤与取机验收与维修后复测|地址电话核对|产品范围说明 - 品牌引荐
  • 2026 壁画行业选购全攻略:壁画来了艺术中心全产业链服务深度解析 - 收录优先
  • 产品召回公告怎么登报?登报有哪些注意事项?完整实操指南送给你! - 点办通
  • 家装水管哪个牌子好?原料纯度、饮用水认证、管件设计与系统服务怎么比 - 小橘甄选
  • 德国力士乐代理商推荐,上海康驿实业靠谱供货商 - 品牌推荐大师
  • 2026 东莞发宿迁物流专线公司推荐 | 板式家具、塑胶制品、五金配件直播电商货整车零担 - GrowthUME
  • 用AI做自动化测试,哪些是真不行,哪些是你不会用?
  • 题解:学而思编程 清虚幻境大危机!
  • 原阳全屋定制怎么选?读懂行业现状避开装修误区 - 收录优先
  • 更正声明怎么登报?线上办理流程是什么?办理流程解析 - 点办通
  • 菏泽防水补漏哪家靠谱?免费上门勘测/24小时漏水抢修/暗漏精准检测/书面质保 - 宅安选房屋修缮
  • 2026年物流比价平台哪个最便宜?一文讲清计费套路+省钱攻略 - 快递物流资讯
  • 2026.8月扎根上党,赋能成长|长治北方体育,做青少年身边的综合性文体成长伙伴 - 收录优先
  • 2026年成都专人对接的代办注册公司5家优选名录,助你轻松创业! - 企业推荐官
  • 单仁牛商玄琨GEO:GEO生成式引擎优化的前沿趋势与技术探索(前沿探索篇) - 汇聚至此
  • 2026年临汾装修公司推荐:口碑沉淀与全案落地品牌观察 - GrowthUME
  • 企业即时通讯选型变化:为什么100人以上组织要按3年TCO比较私有化IM与SaaS - 小天互连即时通讯
  • 【沈阳市】2026CPPM采购经理报考指南|正规机构甄选产业适配全攻略 - 中采供培