【CF715E】Complete the Permutations 第一类斯特林数
题目大意
有两个排列 \(p,q\),其中有一些位置是空的。
你要补全这两个排列。
定义 \(s(p,q)\) 为 每次交换 \(p\) 中的两个数,让 \(p=q\) 的最小操作次数。
求 \(s(p,q)=0,1,2,\ldots,n-1\) 的方案数。
\(n\leq 300\)
题解
考虑 \(s(p,q)\) 怎么求。
对于每一个 \(i\),连一条有向边 \(p_i\to q_i\)。那么 \(s(p,q)\) 就是 \(n-\) 图中环的个数。
先把 \(p,q\) 对应的图建出来,处理一下,算出 \(x\to ?,?\to x,x\to x,?\to ?\) 的边的个数,记为 \(s_1,s_2,s_3,s_4\)。
有一个结论:如果一个环里面同时有前两种边,那么一定有第四种边。
记 \(f_i\) 为用第一种边搞出了 \(i\) 个环的方案数
枚举选了几条边,剩下的边就拿去和第四种边插在一起
\]
\(g_i\) 为用第二种边搞出了 \(j\) 个环的方案数
最后第四种边搞出 \(i\) 个环的方案数 是
\]
因为编号可以随便选,所以还要乘上 \(d!\)
把这三个方案数卷在一起就好了。
时间复杂度:\(O(n^2)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<functional>
#include<cmath>
#include<vector>
#include<assert.h>
//using namespace std;
using std::min;
using std::max;
using std::swap;
using std::sort;
using std::reverse;
using std::random_shuffle;
using std::lower_bound;
using std::upper_bound;
using std::unique;
using std::vector;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
void open(const char *s){
#ifndef ONLINE_JUDGE
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
void open2(const char *s){
#ifdef DEBUG
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
int rd(){int s=0,c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
const int N=310;
const ll p=998244353;
int fa[N],e1[N],e2[N];
int a[N],b[N];
int n;
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
x=find(x);
y=find(y);
e2[x]++;
if(x==y)
return;
e1[y]+=e1[x];
e2[y]+=e2[x];
fa[x]=y;
}
int s1,s2,s3,s4;
ll fac[N],ifac[N],inv[N];
ll f[N],g[N],h[N];
ll ans1[N],ans2[N];
ll s[N][N];
int deg[N];
int c[N];
int c1[N],c2[N],d1[N],d2[N];
ll binom(int x,int y)
{
return fac[x]*ifac[y]%p*ifac[x-y]%p;
}
int main()
{
open("cf715e");
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=1;i<=n;i++)
{
fa[i]=i;
e1[i]=1;
}
for(int i=1;i<=n;i++)
if(a[i]&&b[i])
merge(a[i],b[i]);
for(int i=1;i<=n;i++)
{
if(a[i]&&find(a[i])==find(b[i])&&e1[a[i]]==e2[a[i]])
{
if(find(a[i])==a[i])
s3++;
}
if(a[i])
a[i]=find(a[i]);
if(b[i])
b[i]=find(b[i]);
if(a[i]&&b[i]!=a[i])
{
c1[a[i]]=1;
d1[a[i]]=bool(b[i]);
}
if(b[i]&&a[i]!=b[i])
{
c2[b[i]]=1;
d2[b[i]]=bool(a[i]);
}
}
for(int i=1;i<=n;i++)
if(!a[i]&&!b[i])
s4++;
for(int i=1;i<=n;i++)
{
if(c1[i]&&c2[i]&&!d1[i]&&!d2[i])
s4++;
else
{
if(c1[i]&&!d1[i])
s1++;
if(c2[i]&&!d2[i])
s2++;
}
}
fac[0]=fac[1]=ifac[0]=ifac[1]=inv[1]=1;
for(int i=2;i<=n;i++)
{
inv[i]=(-p/i*inv[p%i]%p+p)%p;
fac[i]=fac[i-1]*i%p;
ifac[i]=ifac[i-1]*inv[i]%p;
}
s[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
s[i][j]=(s[i-1][j-1]+s[i-1][j]*(i-1))%p;
if(s4)
{
for(int i=0;i<=s1;i++)
for(int j=i;j<=s1;j++)
f[i]=(f[i]+binom(s1,j)*s[j][i]%p*fac[s4+s1-j-1]%p*ifac[s4-1])%p;
for(int i=0;i<=s2;i++)
for(int j=i;j<=s2;j++)
g[i]=(g[i]+binom(s2,j)*s[j][i]%p*fac[s4+s2-j-1]%p*ifac[s4-1])%p;
for(int i=0;i<=s4;i++)
h[i]=s[s4][i]*fac[s4]%p;
}
else
{
for(int i=0;i<=s1;i++)
f[i]=s[s1][i];
for(int i=0;i<=s2;i++)
g[i]=s[s2][i];
h[0]=1;
}
for(int i=0;i<=s1;i++)
for(int j=0;j<=s2;j++)
ans1[i+j]=(ans1[i+j]+f[i]*g[j])%p;
for(int i=0;i<=s1+s2;i++)
for(int j=0;j<=s4;j++)
ans2[i+j]=(ans2[i+j]+ans1[i]*h[j])%p;
for(int i=n;i>=1;i--)
printf("%lld ",i-s3>=0?ans2[i-s3]:0);
return 0;
}
【CF715E】Complete the Permutations 第一类斯特林数的更多相关文章
- CF715E Complete the Permutations(第一类斯特林数)
题目 CF715E Complete the Permutations 做法 先考虑无\(0\)排列的最小花费,其实就是沿着置换交换,花费:\(n-\)环个数,所以我们主要是要求出规定环的个数 考虑连 ...
- 【CF715E】Complete the Permutations(容斥,第一类斯特林数)
[CF715E]Complete the Permutations(容斥,第一类斯特林数) 题面 CF 洛谷 给定两个排列\(p,q\),但是其中有些位置未知,用\(0\)表示. 现在让你补全两个排列 ...
- Codeforces 715E - Complete the Permutations(第一类斯特林数)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题.在 AC 此题之前,此题已经在我的任务计划中躺了 5 个月的灰了. 首先考虑这个最短距离是什么东西,有点常识的人(大雾)应该知道, ...
- 【UVA 11077】 Find the Permutations (置换+第一类斯特林数)
Find the Permutations Sorting is one of the most used operations in real life, where Computer Scienc ...
- UVA11077 Find the Permutations —— 置换、第一类斯特林数
题目链接:https://vjudge.net/problem/UVA-11077 题意: 问n的全排列中多有少个至少需要交换k次才能变成{1,2,3……n}. 题解: 1.根据过程的互逆性,可直接求 ...
- 【HDU 4372】 Count the Buildings (第一类斯特林数)
Count the Buildings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- 【组合数学:第一类斯特林数】【HDU3625】Examining the Rooms
Examining the Rooms Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 如何快速求解第一类斯特林数--nlog^2n + nlogn
目录 参考资料 前言 暴力 nlog^2n的做法 nlogn的做法 代码 参考资料 百度百科 斯特林数 学习笔记-by zhouzhendong 前言 首先是因为这道题,才去研究了这个玩意:[2019 ...
- 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT&多项式】permutation
目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...
随机推荐
- C#中的CultureInfo类
CultureInfo类位于System.Globalization命名空间内,这个类和命名空间许多人都不是很熟悉,实际我们在写程序写都经常间接性的接触这个类,当进行数字,日期时间,字符串匹配时,都会 ...
- spring boot整合mybatis方式二
方式二: pom文件导入maven依赖: <dependency> <groupId>org.springframework.boot</groupId> < ...
- JVM的总结
1.JVM的内存模型 JVM主要由程序计数器,虚拟机栈,堆,方法区,本地方法区 1.程序计数器的功能是记录当前线程执行到了字节码文件的哪一行, JVM执行的是.java编译后的.class文件 2.虚 ...
- nginx系列6:nginx的进程结构
nginx的进程结构 如下图: 通过ps –ef | grep nginx可以看到共有三个进程,一个master进程,两个worker进程. nginx是多进程结构,多进程结构设计是为了保证nginx ...
- 《全栈营销之如何制作个人博客》之一:用什么开发语言和CMS系统
现在的互联网,已经不再是初级互联时代,是需要全方位营销,自建粉丝池的时代,云码素材从提出全栈营销,到实践分析,总结出全栈营销第一步,先制作一个个人博客是最好的开始.今天开始就跟我一起学习如何制作一个精 ...
- 解决vue数据渲染过程中的闪动问题
关键代码 主要解决vue双大括号{{}}在数据渲染和加载过程中的闪动问题,而影响客服体验. html代码: <span class="tableTitle selftab" ...
- java基础(三):谈谈java异常的处理
1.知识点总结 1.1.异常分类 异常就是java中出现的不正常的现象(错误与异常),按照继承的体系结构,可以分类如下 Throwable: 它是所有错误与异常的超类(祖宗类) |- Error 错误 ...
- 5分钟入门LingaScript-尝鲜中文版TypeScript
续前文转载: 中文輸進去,程式出得來,開發者發大財 -LingaScript:中文化TypeScript, 虽然其中例程使用了繁体中文语法, 但它同时也支持简体中文语法. 注: 此文中VS Code的 ...
- Dotspatial 要素重叠分析
private void toolStripButton30_Click(object sender, EventArgs e) { //面状重叠分析 if (mapMain.Layers.Count ...
- 【升鲜宝】生鲜配送管理系统_升鲜宝 V2.0 按客户商品分类分开打印配送与按客户商品分类导出相关订单商品相关说明(一)
[升鲜宝]生鲜配送管理系统_升鲜宝 V2.0 按[客户]的商品分类分开打印(配送单)与按[客户]商品分类[对账单]导出相关销售订单商品功能相关说明(一) 业务场景概述与痛点 1.中小学校食堂的客户,每 ...