Solution -「AGC 019E」「AT 2704」Shuffle and Swap
\(\mathcal{Description}\)
Link.
给定 \(01\) 序列 \(\{A_n\}\) 和 \(\{B_n\}\),其中 \(1\) 的个数均为 \(k\)。记 \(A\) 中 \(1\) 的位置为 \(\{a_k\}\),\(B\) 中的为 \(\{b_k\}\)。现任意排列 \(\{a_k\}\) 和 \(\{b_k\}\),然后依次交换 \(A_{a_i}\) 和 \(A_{b_i}\),\(i=1,2,\dots,k\)。求使操作完成后 \(A=B\) 的排列方案数对 \(998244353\) 取模的结果。
\(n\le10^4\)。
\(\mathcal{Solution}\)
首先转化题意——每次操作用 \(A\) 的一个 \(1\) 和 \(B\) 中一个需要 \(1\) 的位置交换,共进行 \(k\) 次操作,求满足条件的方案数。
我们定义 \(A_i=1\land B_i=0\) 的位置为“富余点”——它们需要为其它位置提供 \(1\);\(A_i=B_i=1\) 的位置为“公共点”——它们已经满足条件,但可以作为传递 \(1\) 的载体;\(A_i=0\land B_i=1\) 的位置为“缺失点”——它们是“富余点”需要提供到的位置。
那么,只需要每个“富余点”的 \(1\) 都传递给“缺失点”,\(A\) 就与 \(B\) 相等。考虑一次从一个“富余”到“缺失”的传递,如图:
其中三角形为“缺失点”,圆形为“公共点”(任意多个,亦可不存在),方形为“富余点”。注意若存在“公共点”,传递是不能反向的,这样会导致与三角形相邻的公共点的 \(1\) 变为 \(0\)。(某课件的笔误,注意一下 www。)
考虑 DP,记 \(f(i,j)\) 表示在传递链中用了 \(i\) 个“公共点”,用了 \(j\) 个“富余点”(即有 \(j\) 条传递链)时,传递链中的方案数。边界为 \(f(0,0)=1\),转移:
\]
前一项,将一个公共点加入一条传递链的末尾。有 \(j\) 条链,新的点可以与已有的 \(i-1\) 个点交换(不是交换操作顺序,而是直接交换链中位置),故有系数 \(ij\)。
后一项,新建一条“缺失”-“富余”链。首先拿出新的一对“缺失点”和“富余点”,仍考虑到原来的“缺失点”或“富余点”可以和新点交换位置,故有系数 \(j^2\)。
最后统计答案,发现“公共点”没有必要在链中用完,设在链中用 \(a\) 个“公共点”,还剩下 \(b\) 个。那么在所有“公共点”中选出 \(b\) 个,方案数 \(\binom{a+b}{b}\);公共点内部方案 \((b!)^2\);把这 \(b\) 次操作安排进总共 \(k\) 次操作里,方案数 \(\binom{k}{b}\)。所以设“公共点”有 \(s\) 个,“富余点”有 \(t\) 个,答案为(\(i\) 枚举的是不在链中的“公共点”个数):
\]
复杂度 \(\mathcal O(n^2)\)。
\(\mathcal{Code}\)
#include <cstdio>
#include <cstring>
const int MAXL = 1e4, MOD = 998244353;
int n, sur, bal, f[MAXL + 5][MAXL + 5];
int fac[MAXL + 5], ifac[MAXL + 5];
char A[MAXL + 5], B[MAXL + 5];
inline void addeq ( int& a, const int b ) { if ( ( a += b ) >= MOD ) a -= MOD; }
inline int mul ( long long a, const int b ) { return ( a *= b ) < MOD ? a : a % MOD; }
inline int qkpow ( int a, int b ) {
int ret = 1;
for ( ; b; a = mul ( a, a ), b >>= 1 ) ret = mul ( ret, b & 1 ? a : 1 );
return ret;
}
inline void init () {
fac[0] = 1;
for ( int i = 1; i <= n; ++ i ) fac[i] = mul ( i, fac[i - 1] );
ifac[n] = qkpow ( fac[n], MOD - 2 );
for ( int i = n - 1; ~ i; -- i ) ifac[i] = mul ( i + 1, ifac[i + 1] );
}
inline int comb ( const int n, const int m ) {
return n < m ? 0 : mul ( fac[n], mul ( ifac[m], ifac[n - m] ) );
}
int main () {
scanf ( "%s %s", A + 1, B + 1 );
n = strlen ( A + 1 ), init ();
for ( int i = 1; i <= n; ++ i ) {
if ( A[i] ^ '0' && B[i] ^ '0' ) ++ bal;
else if ( A[i] > B[i] ) ++ sur;
}
f[0][0] = 1;
for ( int i = 0; i <= bal; ++ i ) {
for ( int j = 0, cur; j <= sur; ++ j ) {
if ( ! ( cur = f[i][j] ) ) continue;
addeq ( f[i + 1][j], mul ( cur, mul ( i + 1, j ) ) );
addeq ( f[i][j + 1], mul ( cur, mul ( j + 1, j + 1 ) ) );
}
}
int ans = 0;
for ( int i = 0; i <= bal; ++ i ) {
int fre = bal - i;
int self = mul ( mul ( fac[fre], fac[fre] ),
mul ( comb ( bal + sur, fre ), comb ( bal, fre ) ) );
addeq ( ans, mul ( f[i][sur], self ) );
}
printf ( "%d\n", ans );
return 0;
}
Solution -「AGC 019E」「AT 2704」Shuffle and Swap的更多相关文章
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- 「题解」「美团 CodeM 资格赛」跳格子
目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...
- 【翻译】西川善司的「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,后篇
http://www.4gamer.net/games/216/G021678/20140714079/ 连载第2回的本回, Arc System Works开发的格斗游戏「GUILTY G ...
- Android内存管理(4)*官方教程 含「高效内存的16条策略」 Managing Your App's Memory
Managing Your App's Memory In this document How Android Manages Memory Sharing Memory Allocating and ...
- SSH连接时出现「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」解决办法
用ssh來操控github,沒想到連線時,出現「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」,後面還有一大串英文,這時當然要向Google大神求助 ...
- 「Windows MFC 」「Edit Control」 控件
「Windows MFC 」「Edit Control」 控件
- 「ZJOI2019」&「十二省联考 2019」题解索引
「ZJOI2019」&「十二省联考 2019」题解索引 「ZJOI2019」 「ZJOI2019」线段树 「ZJOI2019」Minimax 搜索 「十二省联考 2019」 「十二省联考 20 ...
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
随机推荐
- Linux上天之路(八)之用户和组
主要内容. 用户创建,删除,修改 密码及密码文件 组创建,删除,修改 组密码及组配置文件 相关文件 Linux用户分类 超级管理员: UID为0 root用户拥有至高无上的命令,root用户不能改名 ...
- Hive的分析函数的使用
原文: https://www.toutiao.com/i6769120000578945544/?group_id=6769120000578945544 我们先准备数据库.表和数据 开窗分析函数相 ...
- IK 分词器
目录 IK 分词器-介绍 IK 分词器-安装 环境准备:Maven 安装 IK 分词器 IK 分词器-使用 IK 分词器-介绍 现有问题:ES 默认对中文分词并不友好,实际上是把中文进行了每个字的分词 ...
- 如何提高docker容器的安全性
一. 概述 Docker 容器一直是开发人员工具箱的重要组成部分,使开发人员能够以标准化的方式构建.分发和部署他们的应用程序.毫无疑问,这种吸引力的增加伴随着容器化技术的相关安全问题.他们可以很容易地 ...
- 使用nexus搭建一个maven私有仓库
使用nexus搭建一个maven私有仓库 大家好,我是程序员田同学.今天带大家搭建一个maven私有仓库. 很多公司都是搭建自己的Maven私有仓库,今天就带大家使用nexus搭建一个自己的私有仓库, ...
- day3 创建数组并完成对数组的操作
1.实现函数action()初始化数据全0的操作 2.实现函数assignment()利用指针给数组赋值0~9 3.实现函数print()打印数组的每个函数 4.实现函数reverse()完成对数组的 ...
- javascript的AMD规法--esl与requirejs浅介。
AMD规范,全称是Asynchronous Module Definition,即异步模块加载机制.从它的规范描述页面看,AMD很短也很简单,但它却完整描述了模块的定义,依赖关系,引用关系以及加载机制 ...
- http状态码 200 304 404 503等
浏览器采用http请求时,会封装http get等信息见下图请求头,然后服务器响应后回发一些信息,包括状态码,响应头,响应信息等等,如下图. 右上图可见两种状态码,一种是200 一种是304.其中20 ...
- vue学习9-更新视图
<!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <meta ht ...
- 返回值Object-注解驱动作用
返回值Object 两个常用实现类 StringHttpMessageConverterhe:负责读取字符串格式的数据和写出字符串格式的数据 MappingJackson2HttpMessageCon ...