Solution -「CF 848D」Shake It!
\(\mathcal{Description}\)
Link.
初始有一个有向图 \(G=(V,E)\),\(V=\{s,t\}\),\(E=\langle s,t\rangle\),一次操作定义为取任意 \(\langle u,v\rangle\in E\),设 \(w\) 为一个新结点,则令 \(V=V\cup\{w\}\),\(E=E\cup \{\langle u,w\rangle,\langle w,v\rangle\}\)。现进行 \(n\) 次操作,求最终有多少个本质不同的 \(G\),满足 \(\operatorname{cut}(s,t)=m\),答案对 \((10^9+7)\) 取模。
\(G\) 与 \(G'\) 本质相同:存在一个 \(s,t\) 均为不动点的 \(f:V_G\rightarrow V_{G'}\),使得 \(f\) 作用于 \(G\) 后有 \(E_G=E_{G'}\)。
\(n,m\le50\)。
\(\mathcal{Solution}\)
灵性的 DP 神题。
我们称一次选取 \(\langle u,v\rangle\) 边的操作为对 \(\langle u,v\rangle\) 的扩展。
令 \(f(i,j)\) 表示 \(i\) 次操作使原图的最大流为 \(j\) 的方案数,可见 \(f(n,m)\) 为答案;同时令 \(F(i,j)\) 为其第二维后缀和,即 \(F(i,j)=\sum_{k\ge j}f(i,j)\)。
然后不难发现完全转移不了。 再令 \(g(i,j)\) 表示对于任意边 \(\langle u,v\rangle\),\(i\) 次操作,扩展且仅扩展 \(\langle u,v\rangle\) 一次,使得 \(u\) 到 \(v\) 的最大流增加 \(j\)(变为 \(j+1\))的方案数;同理定义 \(G(i,j)\)。注意 \(g\) 与 \(f\) 的区别,例如对于下图中的 <绿点, 红点>:
上图的方案都是 \(g(3,1)\) 所包含的,而
都不是 \(g(4,3)\) 所包含的,因为它们都扩展了 <绿点, 蓝点> 这条边多于一次。
接着考虑 \(f\) 与 \(g\) 的关系,有
\]
即,先用一次操作扩展初始的 \(\langle u,v\rangle\),此后 \(\langle u,w\rangle,\langle w,v\rangle\) 都成为 \(f\) 的子问题,只要使两者的最大流同时不小于 \(j\),则 \(u\) 到 \(v\) 增加的流也不小于 \(j\)。并且由于 \(u,v\) 在映射中不动,所有方案均本质不同。
难点在于对 \(f\) 的转移。我们要选取若干个 \(g\) 作用在初始的 \(\langle s,t\rangle\),形成最终的图 \(G\),同时保证方案本质不同。即,找到 \(g(i_1,j_1,),g(i_2,j_2),\cdots,g(i_s,j_s)\),使得 \(\sum i=n\) 且 \(\sum j=m-1\)(\(s\) 到 \(t\) 本身就有 \(1\) 的流)。那么,在转移过程中,仅需考虑在选择方案的末尾加入 \(k\) 个当前的 \(g(i,j)\),\(k\) 个 \(g(i,j)\) 内部的方案用隔板法可知为 \(\binom{g(i,j)+k}{k}\),再乘上原有方案数即可。因为不同 \(g\) 之间钦定无序,相同 \(g\) 之间隔板法保证无序,故方案无序,即本质不同。
到此,复杂度 \(\mathcal O(n^4\ln n)\),瓶颈在于枚举“\(k\) 个当前的 \(g(i,j)\)”。
\(\mathcal{Code}\)
代码中 f[][]
对应 \(F\),g[][]
对应 \(G\),h[][]
对应稍作下标移动的 \(f\)。
/* Clearink */
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
const int MAXN = 50, MOD = 1e9 + 7;
int n, m, ifac[MAXN + 5];
inline int imin( const int a, const int b ) { return a < b ? a : b; }
inline int mul( const long long a, const int b ) { return a * b % MOD; }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
inline int mpow( 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() {
int& t = ifac[MAXN] = 1;
rep ( i, 1, MAXN ) t = mul( t, i );
t = mpow( t, MOD - 2 );
per ( i, MAXN - 1, 0 ) ifac[i] = mul( ifac[i + 1], i + 1 );
}
int f[MAXN + 5][MAXN + 5], g[MAXN + 5][MAXN + 5], h[MAXN + 5][MAXN + 5];
int main() {
init();
scanf( "%d %d", &n, &m );
f[0][1] = h[0][0] = 1;
rep ( i, 1, n ) {
rep ( j, 1, i + 1 ) {
int& crg = g[i][j];
rep ( k, 0, i - 1 ) {
addeq( crg, mul( f[k][j], f[i - k - 1][j] ) );
}
}
rep ( j, 1, i + 1 ) {
int gv = sub( g[i][j], g[i][j + 1] );
per ( a, n, 0 ) per ( b, n + 1, 0 ) {
int crh = 0;
for ( int k = 0, si = 0, sj = 0, up = 1;
si <= a && sj <= b; ++k, si += i, sj += j ) {
addeq( crh, mul( h[a - si][b - sj], mul( up, ifac[k] ) ) );
up = mul( up, add( gv, k ) );
}
h[a][b] = crh;
}
}
per ( j, i + 1, 1 ) {
f[i][j] = add( h[i][j - 1], f[i][j + 1] );
}
}
printf( "%d\n", sub( f[n][m], f[n][m + 1] ) );
return 0;
}
Solution -「CF 848D」Shake It!的更多相关文章
- Solution -「CF 1342E」Placing Rooks
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...
- Solution -「CF 1622F」Quadratic Set
\(\mathscr{Description}\) Link. 求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...
- Solution -「CF 923F」Public Service
\(\mathscr{Description}\) Link. 给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...
- Solution -「CF 923E」Perpetual Subtraction
\(\mathcal{Description}\) Link. 有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ...
- Solution -「CF 1586F」Defender of Childhood Dreams
\(\mathcal{Description}\) Link. 定义有向图 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarr ...
- Solution -「CF 1237E」Balanced Binary Search Trees
\(\mathcal{Description}\) Link. 定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...
- Solution -「CF 623E」Transforming Sequence
题目 题意简述 link. 有一个 \(n\) 个元素的集合,你需要进行 \(m\) 次操作.每次操作选择集合的一个非空子集,要求该集合不是已选集合的并的子集.求操作的方案数,对 \(10^9 ...
- Solution -「CF 1023F」Mobile Phone Network
\(\mathcal{Description}\) Link. 有一个 \(n\) 个结点的图,并给定 \(m_1\) 条无向带权黑边,\(m_2\) 条无向无权白边.你需要为每条白边指定边权 ...
- Solution -「CF 599E」Sandy and Nuts
\(\mathcal{Description}\) Link. 指定一棵大小为 \(n\),以 \(1\) 为根的有根树的 \(m\) 对邻接关系与 \(q\) 组 \(\text{LCA}\ ...
随机推荐
- Linux上天之路(十八)之自动化部署
pexpect Pexpect 是 Don Libes 的 Expect 语言的一个 Python 实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Pyth ...
- 【Warrior刷题笔记】剑指offer 32. 三道题,让你学会二叉树的深度广度优先遍历与递归迭代技术
题目一 剑指 Offer 32 - I. 从上到下打印二叉树 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/cong-shang-dao-xi ...
- FIS Issue 标记
-----已知 [pack问题]忽视<!--[if lt IE 9]>进行合并 https://github.com/fex-team/fis/issues/253 关于增加md5戳以后文 ...
- RabbitMQ 中的分布式,普通 cluster 模式的构建
RabbitMQ 如何做分布式 前言 集群配置方案 cluster 普通模式 镜像模式 federation shovel 节点类型 RAM node Disk node 集群的搭建 1.局域网配置 ...
- 【笔记】论文阅读:《Gorilla: 一个快速, 可扩展的, 内存式时序数据库》
英文:Gorilla: A fast, scalable, in-memory time series database 中文:Gorilla: 一个快速, 可扩展的, 内存式时序数据库
- C++构造函数语义学(三)(基于C++对象模型)
带有虚基类的情况. 1 #include<iostream> 2 using namespace std; 3 class X 4 { 5 public: 6 int i; 7 }; 8 ...
- 微服务架构 | 5.4 Sentinel 流控、统计和熔断的源码分析
目录 前言 1. Sentinel 的自动装配 1.2 依赖引入 1.3 SentinelWebAutoConfiguration 配置类 1.4 CommonFilter 过滤器 1.5 小结 2. ...
- Vue3中的响应式对象Reactive源码分析
Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...
- GDB死锁调试
1.测试代码 代码中开启两个线程,加锁后轮流输出数据,其中一个线程误将pthread_mutex_unlock(),写成pthread_mutex_lock()代码如下: int g_tickets ...
- Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 解决
感谢大佬:https://blog.csdn.net/a704397849/article/details/93797529 springboot + mybatis多数据库 + druid连接池配置 ...