分析性质+dp计数:1007T4

news2024/11/26 19:56:03

http://cplusoj.com/d/senior/p/SS231007D

分析题目性质,有:

  1. 按编号顺序最短路必然为连续段
  2. 边只会在连续段内和相邻连续段之间连
  3. i i i 段 连 i + 1 i+1 i+1 段, i + 1 i+1 i+1 段中每个点恰有1条来自 i i i 的边

然后肯定是考虑 f ( l , r ) f(l,r) f(l,r) 表示最后一段为 [ l , r ] [l,r] [l,r] 的答案,考虑由 f ( k , l − 1 ) f(k,l-1) f(k,l1) 转移

我们可以求出 [ k , l − 1 ] [k,l-1] [k,l1] 中有多少个3度点,多少个2度点。然后记 g ( i , x , y ) g(i,x,y) g(i,x,y) 表示下一层有 i i i 个点,这层有 x x x 个2, y y y 个3度点的方案数。可以用类似递归的方法来推:

g ( i , x , y ) = x × g ( i − 1 , x − 1 , y ) + y × g ( i − 1 , x + 1 , y − 1 ) g(i,x,y)=x\times g(i-1, x-1,y)+y\times g(i-1,x+1,y-1) g(i,x,y)=x×g(i1,x1,y)+y×g(i1,x+1,y1),也就是考虑最后一个点用2度点还是3度点

所以就有 f ( l , r ) = ∑ k < l f ( k , l − 1 ) g ( r − l + 1 , S 2 ( k , l − 1 ) , S 3 ( k , l − 1 ) ) f(l,r)=\sum_{k<l}f(k,l-1)g(r-l+1, S2(k,l-1),S3(k,l-1)) f(l,r)=k<lf(k,l1)g(rl+1,S2(k,l1),S3(k,l1))

我们刚刚计算 g g g 是只考虑块直接的贡献,我们现在要考虑块内的贡献,我们可以计算到 g ( 0 , x , y ) g(0,x,y) g(0,x,y) 里。如果只考虑块内,每个点只能为1度或2度点。我们发现只能长成这个形式:

在这里插入图片描述

我们可以分块统计,枚举多少个2成环,记为 h i h_i hi。我们可以枚举最后一个点所在环的大小,然后乘上一个圆排列。
h i = ∑ h j ( i − j − 1 ) ! 2 ( i − 1 j ) h_i=\sum h_j\frac{(i-j-1)!}2\binom{i-1}j hi=hj2(ij1)!(ji1)

首先对1要量量匹配,方案有 x ! x 2 ! 2 x 2 \large\frac{x!}{\frac x2!2^{\frac x 2}} 2x!22xx!。然后剩下的2直接插板。也就是 g 0 , x , y = ∑ i = 0 y x ! x 2 ! 2 x 2 ( y i ) h i ( y − i + x 2 − 1 x 2 − 1 ) \Large g_{0,x,y}=\sum_{i=0}^y\frac{x!}{\frac x2!2^{\frac x 2}}\binom y ih_i\binom {y-i+\frac x 2-1}{\frac x 2-1} g0,x,y=i=0y2x!22xx!(iy)hi(2x1yi+2x1)

然后往前套即可。

最后一段不会向后连边,所以

a n s = ∑ i = 1 f i , n g 0 , s 2 [ i : n ] , s 3 [ 1 : n ] ans=\sum_{i=1}f_{i,n}g_{0,s2[i:n],s3[1:n]} ans=i=1fi,ng0,s2[i:n],s3[1:n]

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
//#define M
#define mo (int)(1e9+7)
#define N 310
int pw(int a, int b) {
	int ans=1; 
	while(b) {
		if(b&1) ans*=a; 
		a*=a; b>>=1; 
		ans%=mo; a%=mo; 
	}
	return ans; 
}
int fac[N<<2], inv[N<<2], ifac[N<<2]; 
void init(int n) {
	int i; 
	for(i=fac[0]=1; i<=n; ++i) fac[i]=fac[i-1]*i%mo; 
	ifac[n]=pw(fac[n], mo-2); 
	for(i=n-1; i>=0; --i) ifac[i]=ifac[i+1]*(i+1)%mo; 
    for(i=1; i<=n; ++i) inv[i]=ifac[i]*fac[i-1]%mo; 
}
int C(int n, int m) {
	if(m>n) return 0;
	return fac[n]*ifac[m]%mo*ifac[n-m]%mo; 
}
void Add(int &a, int b) {
	a+=b; if(a>=mo || a<=-mo) a%=mo; 
    if(a<0) a+=mo; 
}
const int iv2=pw(2, mo-2); 


int n, m, i, j, k, T;
int s1[N], s2[N], f[N][N], g[N][N][N], h[N], d[N], ans, l, r, x, y;  

int S1(int l, int r) {
	return s1[r]-s1[l-1]; 
}

int S2(int l, int r) {
	return s2[r]-s2[l-1]; 
}

signed main()
{
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
	freopen("graph.in", "r", stdin);
	freopen("graph.out", "w", stdout);
//	srand(time(NULL));
//	T=read();
//	while(T--) {
//
//	}
	n=read(); init(1200); 
	for(i=1; i<=n; ++i) d[i]=read()-1; ++d[1]; 
	for(i=1; i<=n; ++i) if(d[i]==2) ++s2[i]; else ++s1[i]; 
	partial_sum(s1+1, s1+n+1, s1+1); 
	partial_sum(s2+1, s2+n+1, s2+1); 
	h[0]=g[0][0][0]=1; 
	for(i=3; i<=n; ++i) {
		h[i]=fac[i-1]*iv2%mo; 
		for(j=3; j<=i-3; ++j)
			Add(h[i], h[j]*C(i-1, j)%mo*fac[i-j-1]%mo*iv2%mo); 
		g[0][0][i]=h[i]; 
//		printf("h[%lld]=%lld\n", i, h[i]); 
	}
	for(x=2; x<=n; x+=2) 
		for(y=0; y<=n; ++y) {
			k=fac[x]*ifac[x/2]%mo*pw(pw(2, x/2)%mo, mo-2)%mo; 
			for(i=0; i<=y; ++i) {
				Add(g[0][x][y], k*h[i]%mo*C(y, i)%mo*C(y-i+x/2-1, x/2-1)%mo*fac[y-i]%mo); 
//				if(x==4 && y==10) printf("%lld %lld %lld %lld %lld\n", h[i], C(y, i), )
			}
				
//			printf("g [ 0 %lld %lld ] =%lld %lld\n", x, y, g[0][x][y], k); 
		}
	for(i=1; i<=n; ++i) 
		for(x=0; x<=n; ++x) 
			for(y=0; y<=n; ++y) {
				if(x) Add(g[i][x][y], x*g[i-1][x-1][y]%mo); 
				if(y) Add(g[i][x][y], y*g[i-1][x+1][y-1]%mo); 
//				printf("g[%lld][%lld][%lld]=%lld\n", i, x, y, g[i][x][y]); 
			}
	f[2][d[1]+1]=1; 
	for(l=d[1]+2; l<=n; ++l) 
		for(r=l; r<=n; ++r) {
			for(k=1; k<l; ++k) {
				Add(f[l][r], f[k][l-1]*g[r-l+1][S1(k, l-1)][S2(k, l-1)]%mo); 
//				printf("f[%lld][%lld]=%lld %lld %lld(%lld %lld)\n", l, r, f[l][r], f[k][l-1],
//						 g[r-l+1][S1(k, l-1)][S2(k, l-1)], S1(k, l-1), S2(k, l-1)); 
			}
//				printf("f[%lld][%lld]=%lld\n", l, r, f[l][r]); 
		}
	for(i=1; i<=n; ++i) {
		Add(ans, f[i][n]*g[0][S1(i, n)][S2(i, n)]%mo); 
//		printf("[%lld %lld] %lld %lld %lld %lld\n", i, n, f[i][n], S1(i, n), S2(i, n), g[0][S1(i, n)][S2(i, n)]); 
	}
	printf("%lld", (ans%mo+mo)%mo); 
	return 0;
}

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

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

相关文章

Edge浏览器下载文件被保存为 .crdownload 文件的问题小记

问题 近期使用Edge浏览器下载文件时&#xff0c;文件都被保存为 .crdownload 格式的文件了&#xff0c;不确定从哪个版本开始的。除非下载未完成导致文件不完整&#xff0c;否则不会被保存为 .crdownload 格式的文件&#xff1b;实际上文件已完成了下载&#xff0c;且手工修改…

Day4:Linux系统编程1-60P

我的学习方法是&#xff1a;Linux系统编程&#xff08;看pdf笔记&#xff09; Linux网络编程 WebServer 01P-17P Linux相关命令及操作 cp -a dirname1 dirname2 复制目录 cp -r dirname1 dirname2 递归复制目录 1 到目录 2 这里-a 和-r 的差别在于&#xff0c;-a 是完全复制…

深入了解 GMP

视频链接地址:Golang深入理解GPM模型_哔哩哔哩_bilibili 一、Golang“调度器”的由来? (1) 单进程时代不需要调度器 我们知道,一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU。早期的操作系统每个程序就是一个进程,直到一个程序运行完,才能进行下一个进程,就是…

大数据Doris(七):Doris安装与部署规划

文章目录 Doris安装与部署规划 一、软硬件需求 二、​​​​​​​资源规划

[Java] 服务端消息推送汇总

前言&#xff1a;当构建实时消息推送功能时&#xff0c;选择适合的方案对于开发高效的实时应用至关重要。消息的推送无非就推、拉两种数据模型。本文将介绍四种常见的消息实时推送方案&#xff1a;短轮询&#xff08;拉&#xff09;、长轮训&#xff08;拉&#xff09;、SSE&am…

详解C语言指针(二)

文章目录 1. 字符指针2. 指针数组3. 数组指针3.1 什么是数组指针&#xff1f;3.2 &数组名 VS 数组名 4. 数组参数4.1 一维数组传参4.2 二维数组传参 5. 函数指针6. 函数指针数组7. 指向函数指针数组的指针8. 回调函数 1. 字符指针 字符指针是指针类型的变量&#xff0c;其…

文本自动输入/删除的加载动画效果

效果展示 CSS 知识点 绕矩形四周跑的光柱动画实现animation 属性的 steps 属性值运用 页面基础结构实现 <div class"loader"><!-- span 标签是围绕矩形四周的光柱 --><span></span><span></span><span></span>&l…

Git 学习笔记 | 使用码云

Git 学习笔记 | 使用码云 Git 学习笔记 | 使用码云注册登录码云&#xff0c;完善个人信息设置本机绑定SSH公钥&#xff0c;实现免密码登录创建远程仓库 Git 学习笔记 | 使用码云 注册登录码云&#xff0c;完善个人信息 网址&#xff1a;https://gitee.com/ 可以使用微信&…

SpringBoot结合dev-tool 实现IDEA项目热部署

什么是热部署&#xff1f; 应用正在运行的时候升级功能, 不需要重新启动应用对于Java应用程序来说, 热部署就是在运行时更新Java类文件 通俗的来讲&#xff0c;应用在运行状态下&#xff0c;修改项目源码后&#xff0c;不用重启应用&#xff0c;会把编译的内容部署到服务器上…

【Acwing1010】拦截导弹(LIS+贪心)题解

题目描述 思路分析 本题有两问&#xff0c;第一问直接用lis的模板即可&#xff0c;下面重点看第二问 思路是贪心&#xff1a; 贪心流程&#xff1a; 从前往后扫描每一个数&#xff0c;对于每个数&#xff1a; 情况一&#xff1a;如果现有的子序列的结尾都小于当前的数&…

stm32的GPIO寄存器操作以及GPIO外部中断,串口中断

一、学习参考资料 &#xff08;1&#xff09;正点原子的寄存器源码。 &#xff08;2&#xff09;STM32F103最小系统板开发指南-寄存器版本_V1.1&#xff08;正点&#xff09; &#xff08;3&#xff09;STM32F103最小系统板开发指南-库函数版本_V1.1&#xff08;正点&a…

【重拾C语言】七、指针(一)指针与变量、指针操作、指向指针的指针

目录 前言 七、指针 7.1 指针与变量 7.1.1 指针类型和指针变量 7.1.2 指针所指变量 7.1.3 空指针、无效指针 7.2 指针操作 7.2.1 指针的算术运算 7.2.2 指针的比较 7.2.3 指针的递增和递减 7.3 指向指针的指针 前言 指针是C语言中一个重要的概念正确灵活运用指针 可…

单元测试该怎么写

单元测试对于开发人员来说很熟悉&#xff0c;各种语言都提供了单元测试的框架&#xff0c;用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具&#xff0c;使开发人员能够编写和运行测试用例&#xff0c;比较预期行为和实际行为之间的差异&#xff0c;并准确地识…

Android Studio新建项目缓慢解决方案

关于Android Studio2022新建项目时下载依赖慢的解决方案 起因解决方案gradle下载慢解决方案kotlin依赖下载慢解决方案 结尾 起因 新建Android Studio项目时&#xff0c;常会因为网络问题导致部分依赖下载缓慢&#xff0c;其中gradle和kotlin最拖慢进度。 解决方案 gradle下载…

Spring源码解析——IOC属性填充

正文 doCreateBean() 主要用于完成 bean 的创建和初始化工作&#xff0c;我们可以将其分为四个过程&#xff1a; 最全面的Java面试网站 createBeanInstance() 实例化 beanpopulateBean() 属性填充循环依赖的处理initializeBean() 初始化 bean 第一个过程实例化 bean在前面一篇…

四位十进制数字频率计VHDL,仿真视频、代码

名称&#xff1a;四位十进制数字频率计VHDL&#xff0c;quartus仿真 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 使用直接测频法测量信号频率&#xff0c;测频范围为1~9999Hz&#xff0c;具有超量程报警功能 演示视频&#xff1a;四位十进制数字频…

5分钟理解什么是卷积的特征提取

大家好啊&#xff0c;我是董董灿。 卷积算法之所以重要&#xff0c;关键在于其提取特征的能力。 5分钟入门卷积算法中提到&#xff0c;卷积模仿的就是人眼识图的过程&#xff0c;以“感受野”的视角去扫描图片&#xff0c;从而获取不同区域的图片信息。 在这一过程中&#x…

Scratch3.0下载

通俗易懂&#xff0c;直接上链接 链接&#xff1a;https://pan.baidu.com/s/1n-QFEQWT8im8BHQu1wIjtg?pwd1016 提取码&#xff1a;1016

高级IO(Linux)

高级IO 五种IO模型高级IO重要概念同步通信 vs 异步通信阻塞 vs 非阻塞 非阻塞IOfcntl实现函数SetNoBlock轮询方式读取标准输入 I/O多路转接之select初识selectselect函数原型参数解释参数timeout取值关于fd_set结构关于timeval结构函数返回值三级目录 理解select执行过程socket…

多功能频率计周期/脉宽/占空比/频率测量verilog,视频/代码

名称&#xff1a;多功能频率计周期、脉宽、占空比、频率测量verilog 软件&#xff1a;Quartus 语言&#xff1a;Verilog 代码功能&#xff1a; 多功能频率计&#xff0c;可测量信号的周期、脉冲宽度、占空比、频率&#xff0c;语言为verilog&#xff0c;quartus软件设计仿真…