1 条题解
-
0
自动搬运
来自洛谷,原作者为

y2823774827y
喜欢D人的菜鸡搬运于
2025-08-24 22:14:42,当前版本为作者最后更新于2019-12-18 19:24:44,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
序列自动机
- 构造
是字符集,,表示以后的第一个字符的位置,为根节点,整个图是一个
for(LL i=n;i>=1;--i){ for(LL j=1;j<=a;++j) nxt[i-1][j]=nxt[i][j]; nxt[i-1][s[i]]=i; }- 扩展构建
当字符集较大时,可套用可持久化,在叶子节点放一个,表示出边。
相关例题: 字符串小子序列,可持久化序列自动机,维护节点大小。
一步一步(从首到尾)走,有序确定code
经典例题
- 判断是否是原字符串的子序列
构造出了后,从根跑一遍就好了。
- 求子序列个数
从根跑,记忆化搜索,为点为首的子序列个数,
- 求两串的公共子序列个数
两串都构造一下,之间跑就好了。
LL Dfs(LL x,LL y){ if(f[x][y]) return f[x][y]; for(LL i=1;i<=a;++i) if(nxt1[x][i]&&nxt2[y][i]) f[x][y]+=Dfs(nxt1[x][i],nxt2[y][i]); return ++f[x][y]; }- 求字符串的回文子序列个数
原串与反串都建一遍
$$\begin{aligned}\longrightarrow 1~~2~~3~~4~~5~~6~~7~~8~~9~~10&\\ 10~~9~~8~~7~~6~~5~~4~~3~~2~~1&\longleftarrow\\ \end{aligned}$$就相当于从左右端点这样跑。
求的时候显然这个序列才是合法的。
时就是会合了一样,在之后的遍历过程会,所以暂时不统计。
但是其他情况我们都是匹配的两个字符,也就是只会统计,而统计不了,所以在过程中
LL Dfs(LL x,LL y){ if(f[x][y]) return f[x][y]; for(LL i=1;i<=a;++i) if(nxt1[x][i]&&nxt2[y][i]){ if(nxt1[x][i]+nxt2[y][i]>n+1) continue; if(nxt1[x][i]+nxt2[y][i]<n+1) f[x][y]++; f[x][y]=(f[x][y]+Dfs(nxt1[x][i],nxt2[y][i]))%mod; } return ++f[x][y]; }- 求一个的最长公共子序列,使得是的子序列
还是同样的,表示一匹配到的位。
改变一下的构建方法
for(LL i=1;i<=a;++i) nxt[n][i]=n; for(LL i=0;i<n;++i){ for(LL j=1;j<=a;++j) nxt[i][j]=i; nxt[i][c[i+1]]=i+1; }
- 1
信息
- ID
- 4830
- 时间
- 2000ms
- 内存
- 500MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者