[AGC019E]Shuffle and Swap

题目大意:

给出两个长度为\(n(n\le10000)\)的\(01\)串\(A_{1\sim n}\)和\(B_{1\sim n}\)。两个串均有\(k\)个'1'。令\(a_{1\sim k}\)和\(b_{1\sim k}\)分别表示\(A\)和\(B\)中所有'1'出现的位置。将\(a\)和\(b\)等概率随机排列,按\(1\sim k\)的顺序交换\(A_{a_i}\)和\(A_{b_i}\)。令\(P\)表示操作完成后\(A\)与\(B\)相等的概率,求\(P\times(k!)^2\)在模\(998244353\)意义下的值。

思路:

将\(k\)个'1'分为两类:\(S_1\)和\(S_2\)。\(S_1\)表示\(A\)和\(B\)中均为'1',有\(s_1\)个;\(S_2\)表示\(A\)和\(B\)中只有一个为'1',有\(s_2\)个。用\(f[i][j]\)表示\(S_1\)交换完\(i\)个,\(S_2\)交换完\(j\)个后的方案数。

显然,初始情况下,\(S_1\)可以交换\(2\)次,\(S_2\)可以交换\(1\)次。方便起见,假设我们的\(A\)和\(B\)分别为:

110011
111100

对于\(i=0\)的初始情况,由于\(S_2\)之间任意配对都可以使得\(A=B\),因此有\((j!)^2\)种方案。

若我们交换一对\(S_2\),如\(4\)和\(5\),那么交换后,可以交换\(1\)次的\(S_2\)减少了一对。有转移\(f[i][j]+=f[i][j-1]\times j^2\)。

若我们交换一个\(S_1\)和一个\(S_2\),如\(2\)和\(6\),那么交换后,原来那个\(S_2\)已经不能再交换了,而原来可以交换\(2\)次的\(S_1\)现在只能交换一次,可以算入\(S_2\)中,也就是相当于减少了一个\(S_1\)。有转移\(f[i][j]+=f[i-1][j]\times i\times j\)。

最后统计答案时,对于\(S_1\)没有用完的情况,无论如何配对都能满足\(A=B\)。因此\(f[s_1-i][s_2]\)对答案的贡献为\(f[s_1-i][s_2]\times(i!)^2\times\binom{s_1}i\times\binom ki\)。

时间复杂度\(\mathcal O(n^2)\)。

源代码:

#include<cstdio>
#include<cstring>
using int64=long long;
constexpr int N=10001,mod=998244353;
char a[N],b[N];
int fact[N],factinv[N],f[N][N];
void exgcd(const int &a,const int &b,int &x,int &y) {
if(!b) {
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
inline int inv(const int &x) {
int ret,tmp;
exgcd(x,mod,ret,tmp);
return (ret%mod+mod)%mod;
}
inline int C(const int &n,const int &m) {
if(n<m||n<0||m<0) return 0;
return (int64)fact[n]*factinv[m]%mod*factinv[n-m]%mod;
}
int main() {
scanf("%s%s",a,b);
const int n=strlen(a);
for(register int i=fact[0]=1;i<=n;i++) {
fact[i]=(int64)fact[i-1]*i%mod;
}
factinv[n]=inv(fact[n]);
for(register int i=n;i;i--) {
factinv[i-1]=(int64)factinv[i]*i%mod;
}
int s1=0,s2=0;
for(register int i=0;i<n;i++) {
if(a[i]=='1'&&b[i]=='1') s1++;
if(a[i]=='1'&&b[i]=='0') s2++;
}
for(register int i=0;i<=s2;i++) {
f[0][i]=(int64)fact[i]*fact[i]%mod;
}
for(register int i=1;i<=s1;i++) {
for(register int j=1;j<=s2;j++) {
f[i][j]=((int64)f[i-1][j]*i%mod*j%mod+(int64)f[i][j-1]*j%mod*j%mod)%mod;
}
}
int ans=0;
for(register int i=0;i<=s1;i++) {
(ans+=(int64)f[s1-i][s2]*fact[i]%mod*fact[i]%mod*C(s1,i)%mod*C(s1+s2,i)%mod)%=mod;
}
printf("%d\n",ans);
return 0;
}

[AGC019E]Shuffle and Swap的更多相关文章

  1. AGC019-E Shuffle and Swap

    给定两个长度为\(n\le 10^5\)的\(01\)串 \(A, B\), 满足 \(1\) 的数量相等 求通过下列方式将\(A\)变成\(B\)的概率 (mod意义下) 构造序列\(a,b\). ...

  2. AtCoder AGC019E Shuffle and Swap (DP、FFT、多项式求逆、多项式快速幂)

    题目链接 https://atcoder.jp/contests/agc019/tasks/agc019_e 题解 tourist的神仙E题啊做不来做不来--这题我好像想歪了啊= =-- 首先我们可以 ...

  3. Solution -「AGC 019E」「AT 2704」Shuffle and Swap

    \(\mathcal{Description}\)   Link.   给定 \(01\) 序列 \(\{A_n\}\) 和 \(\{B_n\}\),其中 \(1\) 的个数均为 \(k\).记 \( ...

  4. Java_Collections工具类

    Collections 工具类 * Collection与Collections区别 Collection 接口,(大部分集合类的实现接口) Collections 工具类(针对列表) * Colle ...

  5. 【AtCoder】AGC019

    A - Ice Tea Store 算一下每种零售最少的钱就行,然后优先买2,零头买1 #include <bits/stdc++.h> #define fi first #define ...

  6. java学习笔记25(Collections类)

    Collections算法类: Collections是一个算法类,提供了一系列静态方法,实现对集合的排序.替换.交换.搜索.拷贝等操作: 用法:Collections.方法名(要操作的集合): 就像 ...

  7. 集合框架(05)Collections

    1.Collections.sort方法(以及自定义的比较字符串长度排序) package Collections; import java.util.*; class StrLenComparato ...

  8. Java高级部分概要笔记

    复习 多线程 程序.进程.线程的概念.区别 并行.并发 创建线程的四种方式:继承Thread.实现Runnable接口.实现Callable接口.线程池 线程的生命周期 线程的同步方式,三种:同步方法 ...

  9. [LeetCode] Shuffle an Array 数组洗牌

    Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...

随机推荐

  1. Ribbon的主要组件与工作流程

    一:Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接 ...

  2. O(1)时间复杂度实现入栈、出栈、获得栈中最小元素、获得栈中最大元素(转)

    题目要求:定义栈的数据结构,添加min().max()函数(动态获取当前状态栈中的最小元素.最大元素),要求push().pop().min().max()的时间复杂度都是O(1). 思路解析:根据栈 ...

  3. Django【设计】settings方案

      配置文件: 目标:配置文件,默认配置和手动配置分开,参考django的配置文件方案,默认配置文件放在内部,只让用户做常用配置   /bin/settings.py(手动配置) PLUGIN_ITE ...

  4. centos_7.1.1503_src_4

    http://vault.centos.org/7.1.1503/os/Source/SPackages/ libkcompactdisc-4.10.5-3.el7.src.rpm 05-Jul-20 ...

  5. Makefile系列之四 :条件判断

    一.示例 下面的例子,判断$(CC)变量是否“gcc”,如果是的话,则使用GNU函数编译目标. libs_for_gcc = -lgnu normal_libs = foo: $(objects) i ...

  6. Linux设备驱动--内存管理

           MMU具有物理地址和虚拟地址转换,内存访问权限保护等功能.这使得Linux操作系统能单独为每个用户进程分配独立的内存空间并且保证用户空间不能访问内核空间的地址,为操作系统虚拟内存管理模块 ...

  7. linux磁盘占用跟每个文件夹大小总和不符

    1.一种情况是删除了大文件但是没有释放出来,因为有进程还在调用使用 最简单的方法是reboot下服务器再对比下: 2.查看服务器空间使用情况 df -h cd / du -sh *

  8. [ python ] 反射及item系列

    反射 什么是反射? 通过字符串的形式操作对象相关属性.python中的事物都是对象: 关键方法: (1)getattr:获取属性 (2)setattr:设置属性 (3)hashattr:检测是否含有属 ...

  9. ES6 promise简单实现

    基本功能实现: function Promise(fn){ //需要一个成功时的回调 var doneCallback; //一个实例的方法,用来注册异步事件 this.then = function ...

  10. elasticsearch批量删除(查询删除)

    注:delete by query只适用于低于elasticsearch2.0的版本(不包含2.0).有两种形式: 1.无请求体 curl -XDELETE 'localhost:9200/twitt ...