AtCoder Beginner Contest 327 G. Many Good Tuple Problems(带标号二分图计数+有区别小球放入有区别盒子)

news2024/11/24 5:55:01

题目

一个长为n(n<=30)的原始序列x,x[i]可以取值0或1

一个长为m(m<=1e9)的点对序列(s,t),

s序列第i项和t的第i项(s_{i},t_{i}),均可以取值[1,n],

如果构造好s和t后,对任意(s_{i},t_{i})都存在01序列x使得x_{s_{i}}\neq x_{t_{i}}

则称这个序列是合法的,问n^{2*m}种(s,t)序列中,有多少合法序列,

答案对998244353取模

思路来源

官方题解

https://www.cnblogs.com/chasedeath/p/14567667.html

题解

考虑1-n共n个点的不含自环的有向图,C_{n}^{2}条边,如果可以用(i,j)边,表示x[i]\neq x[j]

而最终x是要被化成两堆的,一堆0一堆1,也就是一个二分图

要求二分图的某一个带标号的边集方案只能被计一次,

有向图不好统计,可以考虑看成无向图,也就是(1,2)和(2,1)看成一种边

最后填入m个位置后再决定翻不翻转,再乘上对应的2^m种选法

所以,需要统计的是有标号二分图的方案数

有标号二分图计数

g[i][j]表示i个点j条边的二分图方案数,允许重复

g[i][j]=\sum_{k=1}^{i-1}C_{i}^{k}C_{k*(i-k)}^{j}

即枚举二分图左边选了k个点,右边选了i-k个点,k*(i-k)条边里选j条,

这样的话,一个有着t个连通块的二分图会被计数2^t次,

因为对应连通块部分可以左右互换,从而在另一种合法答案中被统计到

于是考虑怎么去重

h[i][j]表示i个点j条边连通的二分图,

然而连通块数定义在状态里不好用于转移,所以后续的计数考虑容斥

通过g[i][j]减掉不合法的方案,

枚举最后一个点所在的连通块多大,

对应连通块和之前的二分图是在什么时候断裂的

当大小为k时,从i-1个点中选k-1个点,再对应选出一些边

h[i][j]=g[i][j]-\sum_{k=1}^{i-1}\sum_{l=0}^{j}C_{i-1}^{k-1}*h[k][j]*g[i-k][j-l]

有了联通的二分图之后,再考虑如何合并

f[i][j]表示i个点j条边由若干个连通块组成、无重复的二分图

转移仍然枚举最后一个点所在的连通块多大,

从之前的f合法方案,通过背包转移到新的合法方案

当大小为k时,从i-1个点中选k-1个点,再对应选出一些边

f[i][j]=\frac{h[i][j]}{2}+\sum_{k=1}^{i-1}\sum_{l=0}^{j}C_{i-1}^{k-1}*\frac{h[k][l]}{2}*f[i-k][j-l]

求出f[i][j]后,n个点是固定的,

因为f[n-1][j]可以通过不用边的方式转移到f[n][j]

所以,只需要用到f[n][j]的状态,无需再遍历f[i<n][j]的值

当有j条边时,需要满足j条边填到m个位置,j条边都至少出现一次,不然计数就会有重复

小球放盒问题
方法一

这等价于m个有区别的小球放入j个有区别的盒子,每个盒子不能为空

而第二类斯特林数S(m,j)为m个有区别的小球放入j个无区别的盒子的方案数,

所以求出乘上j个盒子的顺序即可,代码中用dp2[i]表示

方法二

互换小球和盒子,

dp[i]表示恰有i种球被放到了m个盒子里,每个盒子只能放一个球

那么就需要用全量的情况,减掉不合法的情况

dp[i]=i^m-\sum_{j=1}^{i-1}C_{i}^j*dp[j]

代码

// Problem: G - Many Good Tuple Problems
// Contest: AtCoder - HHKB Programming Contest 2023(AtCoder Beginner Contest 327)
// URL: https://atcoder.jp/contests/abc327/tasks/abc327_g
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<ll,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define scll(a) scanf("%lld",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N=31,M=N*N,mod=998244353,inv2=(mod+1)/2;
int t,n,m,f[N][M],g[N][M],h[N][M],c[M][M],dp[M],dp2[M];
void ADD(int &x,int y){
	x=(x+y)%mod;
}
int modpow(int x,int n,int mod){
	int res=1;
	for(;n;n>>=1,x=1ll*x*x%mod){
		if(n&1)res=1ll*res*x%mod;
	}
	return res;
}
int C(int x,int y){
	if(x<0 || y<0 || x<y)return 0;
	return c[x][y];
}
void sol(){
	sci(n),sci(m);
	c[0][0]=1;
	rep(i,1,M-1){
		c[i][0]=c[i][i]=1;
		rep(j,1,i-1){
			c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
		}
	}
	rep(i,1,M-1){
		dp[i]=modpow(i,m,mod);
		rep(j,1,i-1){
			ADD(dp[i],mod-1ll*c[i][j]*dp[j]%mod);
		}
		//printf("i:%d f:%d\n",i,dp[i]);
	}
	rep(i,1,M-1){
		rep(j,1,i){
			int sg=((i-j)&1)?-1:1;
			ADD(dp2[i],(1ll*sg*C(i,j)%mod*modpow(j,m,mod)%mod)%mod);
		}
		//printf("i:%d f:%d\n",i,dp2[i]);
	}
	int ans=0;
	rep(i,1,n){
		int up=i*(i+1)/4;
		rep(j,0,up){
			rep(k,0,i){
				ADD(g[i][j],1ll*C(i,k)*C(k*(i-k),j)%mod);
			}
			h[i][j]=g[i][j];
			rep(k,1,i-1){
				rep(l,0,j){
					ADD(h[i][j],mod-1ll*C(i-1,k-1)*h[k][l]%mod*g[i-k][j-l]%mod);
				}
			}
			f[i][j]=1ll*h[i][j]*inv2%mod;
			rep(k,1,i-1){
				rep(l,0,j){
					ADD(f[i][j],1ll*C(i-1,k-1)*h[k][l]%mod*f[i-k][j-l]%mod*inv2%mod);
				}
			}
			//printf("i:%d j:%d 1:%d 2:%d 3:%d\n",i,j,g[i][j],h[i][j],f[i][j]);
			//printf("i:%d j:%d f:%d\n",i,j,f[i][j]);
			//if(i==n && j<=m)printf("i:%d j:%d f:%d dp:%d add:%d\n",i,j,f[i][j],dp[j],1ll*f[i][j]*dp[j]%mod);
			if(i==n)ADD(ans,1ll*f[i][j]*dp[j]%mod);
		}
	}
	//pte(ans);
	ans=1ll*ans*modpow(2,m,mod)%mod;
	pte(ans);
}
int main(){
	t=1;//sci(t); // t=1
	while(t--){
		sol();
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1174166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于8086家具门安全控制系统设计

**单片机设计介绍&#xff0c;基于8086家具门安全控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 # 8086家具门安全控制系统设计介绍 8086家具门安全控制系统是一种用于保护家具和保证室内安全的系统。该系统基于808…

类的成员函数总结

前言&#xff1a; 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成的…

【java学习—十三】处理流之一:缓冲流(1)

文章目录 0. 引言1. 缓冲流2. 缓冲字节流2.1. 缓冲字节输入流2.2. 缓冲字节输出流2.3. 缓冲流实现文件的复制 3. 缓冲字符流 0. 引言 上一章节讲了&#xff1a;文件字符流和字节流&#xff08;基于硬盘&#xff09; 其中&#xff0c;用到的方法有&#xff1a;FlieInuputStream、…

JDBC简单流程

Step1&#xff1a;加载对应数据库&#xff08;比如mysql、oracle、sqlserver&#xff09;的驱动器 1、以mysql驱动器为例&#xff0c;下载好对应的jar包后&#xff0c;在项目对应目录下新建一个lib文件夹&#xff0c;将jar包复制到该文件夹中。 2、然后选中改jar包&#xff0…

链队的练习

链队的练习 相关内容&#xff1a;队列的链式存储结构&#xff08;链队&#xff09; //链队的初始化、入队、出队、取对头 #include<stdio.h> #include<malloc.h> #define OK 1 #define ERROR 0 typedef int Status; //结点结构 typedef struct QNode{ int data; …

单链表的应用(1)

移除链表元素 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 思路&#xff1a;&#xff08;1&#xff09;创建三个结构体指针&#xff0c;分别代表一条新链表的头newhead&#xff0c;…

2023 electron最新最简版打包、自动升级详解

这里我将讲解一下从0搭建一个electron最简版架子&#xff0c;以及如何实现打包自动化更新 之前我有写过两篇文章关于electron框架概述以及 常用api的使用&#xff0c;感兴趣的同学可以看看 Electron桌面应用开发 Electron桌面应用开发2 搭建electron 官方文档&#xff1a;ht…

基于变色龙算法的无人机航迹规划-附代码

基于变色龙算法的无人机航迹规划 文章目录 基于变色龙算法的无人机航迹规划1.变色龙搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用变色龙算法来优化无人机航迹规划。 1.变色龙…

5 ip的分配

如上一节所述&#xff0c;需要和其他设备通信&#xff0c;那么需要先配置ip. 1、如何配置ip 1.可以使用 ifconfig&#xff0c;也可以使用 ip addr 2.设置好了以后&#xff0c;用这两个命令&#xff0c;将网卡 up 一下&#xff0c;就可以了 //---------------------------- 使…

VBA技术资料MF79:将范围级别由工作簿变更为工作表

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…

JavaEE-博客系统2(功能设计)

本部分内容&#xff1a;实现博客列表页&#xff1b;web程序问题的分析方法&#xff1b;实现博客详情页&#xff1b; 该部分的代码如下&#xff1a; WebServlet("/blog") public class BlogServlet extends HttpServlet {//Jackson ObjectMapper类(com.fasterxml.jac…

吴恩达《机器学习》6-1->6-3:分类问题、假设陈述、决策界限

一、什么是分类问题&#xff1f; 在分类问题中&#xff0c;我们试图预测的变量&#x1d466;是离散的值&#xff0c;通常表示某种类别或标签。这些类别可以是二元的&#xff0c;也可以是多元的。分类问题的示例包括&#xff1a; 判断一封电子邮件是否是垃圾邮件&#xff08;二…

软件测试工作流程

流程体系介绍 在以往的项目工作中&#xff0c;我参与过&#xff0c;需求评审、测试计划制定、测试用例编写、测试用例执行、测试脚本编写、测试脚本的执行&#xff0c;进行回归测试、验收测试、编写阶段性测试报告等工作 需求分析&#xff0c;需求评审&#xff08;RPD、产品原…

基于单片机的车载太阳能板自动跟踪系统研究

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、总体设计开发流程二、机械结构设计与研究3.1 机械系统总体设计3.1.1 太阳能板折叠传动 三、太阳能自动跟踪系统硬…

chrome插件开发:popup.html 页面获取当前页面【当前视窗】的url

chrome插件开发&#xff1a;popup.html 页面获取当前页面【当前视窗】的url 开发前的准备 在manifest页面配置上 tabs 权限&#xff0c;否则无法使用tabs接口权限 {"name": "My extension",..."permissions": ["tabs"],... }参考手…

【Linux】第十二站:进程

文章目录 1.windows和linux中的进程2.先描述3.在组织4.具体的Linux系统是如何做的&#xff1f;1.基本概念2.描述进程-PCB3.task_struct和PCB的关系4.task_struct内容分类5.linux具体如何做的&#xff1f;6.查看进程 1.windows和linux中的进程 一个已经加载到内存的程序&#xf…

python获取电脑所连接的wifi密码

电脑连接wifi后&#xff0c;很难直观地看到当前连接wifi的密码&#xff0c;需要借助命令行公管局才可以查看到相关信息。 CMD命令 查看所有已保存的wifi配置信息 netsh wlan show profiles查看某一个wifi的详细信息&#xff0c;需要输入wifi名称来查询 netsh wlan show pro…

小户型工业风,陌生上开花知书香。福州中宅装饰,福州装修

漫步陌上 只因陌上花开 花是自然的那种 朴素而恬淡&#xff0c;不落尘俗。—徐志摩 小户型工业风格 满足业主需求 筑造书香押韵家 从动线、色彩、选材、定制等各个环节 与业主一起畅谈家的构造 形成别“居”一格的温暖品质家 以书做墙 告别电视墙 这是一个实用性很强的…

鲜花展示预约小程序的内容有有哪些

鲜花店市场规模非常高&#xff0c;一方面是鲜花的用途广泛且需求量增加&#xff0c;另一方面则是入行门槛低&#xff0c;很多城市一条街就有可能汇聚了多家门店&#xff0c;尤其是节假日&#xff0c;对客流量高的门店则更加考验&#xff0c;如花束选购预约、信息展示及客户咨询…