\(\mathscr{Description}\)

  Private link.

  令 \(\Sigma=\{\texttt a,\texttt b\}\),对于所有形式语言 \(L\subseteq\Sigma^n\),\(L\) 的最小 DFA 状态数的最大值,以及取到这一最大值时,\(|L|\) 的最小值和最大值。

  \(n\le10^3\)。

\(\mathscr{Solution}\)

  引理 对于任意串 \(x,y\in\Sigma^\star\),定义 \(x\equiv_Ly\),当且仅当 \(\forall z\in\Sigma^\star,xz\in L\equiv yz\in L\)。语言 \(L\) 的最小 DFA 状态数就是等价关系 \(\equiv_L\) 在 \(\Sigma^\star\) 上划分出的等价类数目。

  直接考虑 \(L\) 的最小 DFA 的形态,可以发现:

  • 对于任意状态,从开始状态转移到它的路径长度唯一;
  • 不存在两个状态的转移完全相同(输入同样字符,转移向同一个状态)。

  根据性质一,我们将 DFA 的 DAG 分层,那么总状态数就是每层的状态数之和。令 \(Q_i~(i=0,1,\dots,m)\) 为第 \(i\) 层的状态,则 \(Q_0=\{q_s\}\) 为开始状态,\(Q_m=\{q_t\}\) 为唯一接受状态,此时对于第 \(k\) 层,从 \(Q_{k-1}\) 对 \(Q_k\) 的限制来看,显然 \(|Q_k|\le2|Q_{k-1}|\);从 \(Q_{k+1}\) 对 \(Q_k\) 的限制来看,为了满足性质二,\(Q_{k+1}\) 最多为 \(Q_k\) 内的某个点提供 \((|Q_{k+1}|+1)^2-1\) 种转移的选择(\(1\) 表示空状态,即分别枚举 \(\texttt a\) 和 \(\texttt b\) 转移向谁,不能同时为空)。根据这一构造,每个 \(|Q_k|\) 的上界显然可以同时取到,所以第一问就解决了。

  设 \(Q_p\) 为最后一层满足 \(Q_p=2|Q_{p-1}|\) 的状态,此后,\(Q_k\) 的大小都将由性质二的限制决定。前后都已经固定,\(|L|\) 只取决于 \(\delta_p:Q_p\times\Sigma\rightarrow Q_{p+1}\) 的长相。

  先来刻画 \(Q_{p+1}\) 内每个点对应的后缀串数量。令 \(G_k(x)~(k=p+1,\dots,m)\) 表示 \(Q_k\) 中,状态数量关于状态对应后缀串数量的 GF,那么 \(G_k(x)=(G_{k+1}(x)+1)^2-1\),其实就是 \(G_k(x)=(x+1)^{2^{m-k}}-1\)。

  然后,讨论一下 \(|Q_p|\) 和 \(|Q_{p+1}|\) 的大小关系:

  若 \(|Q_p|<|Q_{p+1}|\),注意到此时必然有 \(|Q_{p+1}|=2|Q_p|+1\),\(\delta_p\) 的当务之急是让每个 \(q\in Q_{p+1}\) 都有前驱。因此先让 \(Q_p\) 内每个点随便在 \(Q_{p+1}\) 里连两个,剩下一个状态放弃一个转移最小化 \(|L|\),增加一个到 \(Q_{p+1}\) 内后缀最多的状态的转移最大化 \(|L|\)。

  若 \(|Q_p|\ge|Q_{p+1}|\),我们需要同时关注“每个状态都有前驱”以及“最小/最大化 \(L\)”的要求。先描述出“在 \(Q_{p+1}\) 里连两个后继”的贡献,令 \(F(x)\) 表示连接方案数关于连接到后继的后缀总数的 GF,那么 \(F(x)=(G_{p+1}(x)+1)^2-1=(x+1)^{2^{m-p+1}}-1\)。接着贪心考虑最小化与最大化 \(L\) 的构造方案:

  • 最小化 \(|L|\),先用 \(Q_p\) 内的 \(|Q_{p+1}|\) 个状态直接各自连一条转移边到 \(Q_{p+1}\) 内的状态,求到剩下能选的连接方案的 GF \(F_1(x)\),在 \(F_1(x)\) 里按指标升序贪心选择。
  • 最大化 \(|L|\),先用 \(Q_p\) 内的 \(|Q_{p+1}|\) 个状态直接各自连一条转移边到 \(Q_{p+1}\) 内的状态,再连一条转移边到 \(Q_{p+1}\) 内后缀串最多的状态,其余和最小化类似。

  撇开高精度计算,复杂度是 \(\mathcal O(n)\) 的。

\(\mathcal{Code}\)

# Rainybunny #

import sys

if __name__ == "__main__":
sys.stdin = open('dfa.in', 'r')
sys.stdout = open('dfa.out', 'w') n = int(input())
ans = [0 for _ in range(3)] m = 0
while 1 << m + 1 <= n - m - 1: m += 1
## the last limited level's G.F. is f_m(x)=(x+1)^{2^m}-1.
# sys.stderr.write(str(m) + '\n') ans[0] = (1 << n - m) - 1
for i in range(0, m + 1):
ans[0] += (1 << (1 << i)) - 1 lef = 1 << n - m - 1; rig = (1 << (1 << m)) - 1
if (lef < rig):
sys.stderr.write('type 1\n')
ans[1] = 1 << ((1 << m) + m - 1)
ans[2] = ans[1] + (1 << m)
else:
sys.stderr.write('type 2\n')
## get f_m(x)(->bino[0]) and f_m^2(x)(->bino[1])
bino = [[0 for _ in range((1 << m) + 1)],
[0 for _ in range((1 << m + 1) + 1)]]
bino[0][0] = bino[1][0] = 1
for i in range(1, (1 << m) + 1):
bino[0][i] = bino[0][i - 1] * ((1 << m) - i + 1) // i
for i in range(1, (1 << m + 1) + 1):
bino[1][i] = bino[1][i - 1] * ((1 << m + 1) - i + 1) // i ## get ans[1].
for i in range(1, (1 << m) + 1):
ans[1] += i * bino[0][i]
bino[1][i] -= bino[0][i]
rest = lef - rig; cur = 1
while rest and rest > bino[1][cur]:
ans[1] += bino[1][cur] * cur
rest -= bino[1][cur]
cur += 1
ans[1] += cur * rest ## get ans[2].
for i in range(1, (1 << m) + 1):
ans[2] += bino[0][i] * (i + (1 << m))
bino[1][i] += bino[0][i] # recover it
bino[1][i + (1 << m)] -= bino[0][i]
rest = lef - rig; cur = 1 << m + 1
while rest and rest > bino[1][cur]:
ans[2] += bino[1][cur] * cur
rest -= bino[1][cur]
cur -= 1
ans[2] += cur * rest print("%d %d %d" % (ans[0], ans[1], ans[2])) sys.stdin.close()
sys.stdout.close()

Solution -「LOCAL」Minimal DFA的更多相关文章

  1. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  2. Solution -「LOCAL」大括号树

    \(\mathcal{Description}\)   OurTeam & OurOJ.   给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...

  3. Solution -「LOCAL」过河

    \(\mathcal{Description}\)   一段坐标轴 \([0,L]\),从 \(0\) 出发,每次可以 \(+a\) 或 \(-b\),但不能越出 \([0,L]\).求可达的整点数. ...

  4. Solution -「LOCAL」Drainage System

    \(\mathcal{Description}\)   合并果子,初始果子的权值在 \(1\sim n\) 之间,权值为 \(i\) 的有 \(a_i\) 个.每次可以挑 \(x\in[L,R]\) ...

  5. Solution -「LOCAL」Burning Flowers

      灼之花好评,条条生日快乐(假装现在 8.15)! \(\mathcal{Description}\)   给定一棵以 \(1\) 为根的树,第 \(i\) 个结点有颜色 \(c_i\) 和光亮值 ...

  6. Solution -「LOCAL」画画图

    \(\mathcal{Description}\)   OurTeam.   给定一棵 \(n\) 个点的树形随机的带边权树,求所有含奇数条边的路径中位数之和.树形生成方式为随机取不连通两点连边直到全 ...

  7. Solution -「LOCAL」ZB 平衡树

    \(\mathcal{Description}\)   OurOJ.   维护一列二元组 \((a,b)\),给定初始 \(n\) 个元素,接下来 \(m\) 次操作: 在某个位置插入一个二元组: 翻 ...

  8. Solution -「LOCAL」舟游

    \(\mathcal{Description}\)   \(n\) 中卡牌,每种三张.对于一次 \(m\) 连抽,前 \(m-1\) 次抽到第 \(i\) 种的概率是 \(p_i\),第 \(m\) ...

  9. Solution -「LOCAL」充电

    \(\mathcal{Description}\)   给定 \(n,m,p\),求序列 \(\{a_n\}\) 的数量,满足 \((\forall i\in[1,n])(a_i\in[1,m])\l ...

  10. Solution -「LOCAL」「cov. 牛客多校 2020 第五场 C」Easy

    \(\mathcal{Description}\)   Link.(完全一致)   给定 \(n,m,k\),对于两个长度为 \(k\) 的满足 \(\left(\sum_{i=0}^ka_i=n\r ...

随机推荐

  1. 洛谷 P1540 [NOIP2010 提高组] 机器翻译

    题目概括 给定 N 个整数,和一个容量为 M 的"字典",从头到尾依次翻译,每次翻译先看自家字典,没有的话再看别人的字典并存到自家字典,如果自家字典满了,当前单词的翻译会代替最早进 ...

  2. 题解:CF771A Bear and Friendship Condition

    CF771A Bear and Friendship Condition 题解 算法 并查集,图的基本性质 分析 题目意思是,一旦有一些点联通,那么这些点必须两两直接相连.换句话讲,就是图中的每个联通 ...

  3. Java核心知识体系10-线程管理

    Java系列 Java核心知识体系1:泛型机制详解 Java核心知识体系2:注解机制详解 Java核心知识体系3:异常机制详解 Java核心知识体系4:AOP原理和切面应用 Java核心知识体系5:反 ...

  4. HTTP相关返回值异常如何解决(下篇)

    ​ 今天我们讲讲HTTP相关返回值异常如何解决(实例持续更新中) 一.4xx客户端错误状态码  这些状态码表示请求有问题,通常是由于客户端的错误引起的. 1.1 400 Bad Request: 请求 ...

  5. (Python基础教程之四)Python中的变量的使用

    Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...

  6. An expression evaluator

    An expression evaluator  Download source code (17 kb) Two weeks ago, I saw an article on codeproject ...

  7. Linux之远程挂载SSHFS

    SSHFS(Secure SHell FileSystem)是一个客户端,可以让我们通过 SSH 文件传输协议(SFTP)挂载远程的文件系统并且在本地机器上和远程的目录和文件进行交互. SFTP 是一 ...

  8. 升级Linux内核版本

    ```shell# 查看内核版本,jw版本ceph默认format=2, 2.x 及之前的的内核版本需手动调整format=1# 4.x之前要关闭object-map fast-diff deep-f ...

  9. jackson 中对 null 的处理

    前情提要: 在项目中如何将null值转变为空字符串呢? @Configuration public class JacksonConfig { @Bean @Primary @ConditionalO ...

  10. Java框架 —— MyBatis

    MyBatis 简介  持久层框架,半自动映射,支持自定义SQL.高级映射.存储过程,免除了JDBC代码.参数设置.获取结果集的工 作,可以通过XML或注解方式配置.映射接口,以及实体类在数据库中的记 ...