题意: 给一个1e5的串str,然后有三个起始空串,不超过1000次操作,对三个字符串的一个尾部加一个字符或者减一个字符,保证每个字符不会超过250 每次操作之后询问你这三个串是不是可以组成str的子序列, 比如ab,cd,ef可以组成acgbdef的子序列 思路: dp[i][j][k]为三个串分别匹配到i,j,k的时候组成的子序列的最后一个字符在str中的位置,如果dp[strlen(str1)][strlen(str2)][strlen(str3)]>n则输出no 对每一次询问我们可以处理…
给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1] 内的字符串. 输出格式: 在一行中输出至多删掉其中 3 个字符后不同字符串的个数. 输入样例: ababcc 输出样例: 25 提示: 删掉 0 个字符得到 "ababcc". 删掉 1 个字符得到 "babcc", "aabcc", "abbcc&quo…
题目链接: https://codeforces.com/contest/1150/problem/D 题意: 给出长度为$n$的字符串,和$q$次询问 每次询问是,给$x$宗教增加一个字符$key$,或者让$x$宗教的字符串长度减一 问是否给原字符串染色,每个字符只能染上一种颜色,把相同颜色字符串按顺序取出刚好是每个宗教的字符串 数据范围: $1 \leq n \leq 100\,000$$1 \leq q \leq 1000$ 分析: 定义状态$DP[x][y][z]$,为考虑1号宗教字符串…
题目:http://codeforces.com/contest/1150/problem/D 老是想着枚举当前在给定字符串的哪个位置,以此来转移. 所以想对三个串分别建 trie 树,然后求出三个trie树上各选一个点的答案.那么从“在三个trie树的根,在给定字符串的0位置”开始扩展. 当然 TLE 了. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #…
题目链接 洛谷P4608 题解 建个序列自动机后 第一问暴搜 第二问dp + 高精 设\(f[i][j]\)为两个序列自动机分别走到\(i\)和\(j\)节点的方案数,答案就是\(f[0][0]\) 由于空间卡的很紧,高精不仅要压位,还要动态开内存 由于有些状态是没用的,记忆化搜索以减少内存损失 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include…
题目链接 BZOJ4032 题解 首先膜\(hb\) 空手切神题 一问\(hash\),二问枚举 三问\(trie\)树,四问\(dp\) 南二巨佬神\(hb\) 空手吊打自动机 \(orz orz orz orz orz orz orz\) 咳.说正解 要处理子串,直接搬上后缀自动机 要处理子序列,直接搬上序列自动机[雾] 何为序列自动机 序列自动机其实很简单,就是具有识别所有子序列功能的自动机 建机原理及过程及其简单,只需要从后往前扫一遍,对每一个位置建立一个节点,该节点的各个边连向最晚出现…
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以不连续的一段,例如bde是abcdef的子串,但bdd不是. 下面,给两个小写字母串A,B,请你计算: (1) A的一个最短的子串,它不是B的子串 (2) A的一个最短的子串,它不是B的子序列 (3) A的一个最短的子序列,它不是B的子串 (4) A的一个最短的子序列,它不是B的子序列 输入 有两行…
题目链接 BZOJ4416 题解 建立序列自动机,即预处理数组\(nxt[i][j]\)表示\(i\)位置之后下一个\(j\)出现的位置 设\(f[i]\)表示合法字符集合为\(i\)的最短前缀,枚举最后一个加入的字符进行转移 注意到合法串长度是\(O(n^2)\)级别的,所以\(n > 21\)直接判掉 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio>…
好像序列自动机还没有写过- 串长为n的串共有n+1个节点,除了串中的n个节点,还有一个空的根节点放在串首.每个节点至多有26条出边,每条边连向它之后的第一个字符. 串中的任意一个子序列对应了一条根到某个节点的路径.且每条路径对应一个不同的子序列. 每个节点的parent是这个字母上一次出现的位置.更新只要沿parent指针扫描即可. FJOI2016 所有公共子序列问题 这题暴力建trie能过80真是悲伤(因为按FJOI命题风格这题没有写数据范围 建完序列自动机暴力DP即可 #include <…
题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; ; + ; typedef long long ll; char st…
序列自动机: 是一个处理子序列的自动机.就这样. 建造:(By猫老师:immoralCO猫) s[] next[][] memset(next[n], -, <<); for(int i = n; i; --i) { memcpy(next[i - ], next[i], << ); next[i - ][s[i] - 'a'] = i; } nxt[][]数组就是第几个位置,序号为几的出边连接到第几个位置(位置是对应字符串的位置,其实并没用) 大概原理就是每当要循环到字符串中的一…
题目链接 1.求A的最短子串,它不是B的子串. 子串是连续的,对B建SAM,枚举起点,在SAM上找到第一个无法匹配点即可.O(n)用SAM能做吗..开始想错了. 2.求A的最短子串,它不是B的子序列. 子序列...直接建SAM没啥用.考虑A[i]和上一位A[i-1],用f[i][j]表示到A[i]匹配到B[j]时连续的A的子串长度,如果A[i]==B[j],则f[i][j]=max{f[i-1][k]+1}(k<j). 是取max啊,因为B会尽可能匹配.枚举完B[n]后且max{f[i][k]}…
链接:https://ac.nowcoder.com/acm/contest/392/J 来源:牛客网 题目描述 月月和华华一起去吃饭了.期间华华有事出去了一会儿,没有带手机.月月出于人类最单纯的好奇心,打开了华华的手机.哇,她看到了一片的QQ推荐好友,似乎华华还没有浏览过.月月顿时醋意大发,出于对好朋友的关心,为了避免华华浪费太多时间和其他网友聊天,她要删掉一些推荐好友.但是为了不让华华发现,产生猜疑,破坏了他们的友情,月月决定只删华华有可能搭讪的推荐好友. 月月熟知华华搭讪的规则.华华想与某…
反思 三维的dp压根没看出来,看题解以后思路又很直观,找几道字符串dp练练才行 序列自动机和优化一维略 /* __ __ * ____| |_____| |____ * | | * | __ | * | | * | > <. | * | | * | | * | ... ⌒ ... | * | | * | | * |___ __| * | | * | | Code is far away from bug with the animal protecting * | | 神兽保佑,代码无bug…
[BZOJ4032][HEOI2015]最短不公共子串(后缀自动机,序列自动机) 题面 BZOJ 洛谷 题解 数据范围很小,直接暴力构建后缀自动机和序列自动机,然后直接在两个自动机上进行\(bfs\),找到的第一个不同时存在的节点就直接输出就好了. #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; #define MAX 404…
题目链接:https://nanti.jisuanke.com/t/38232 题目大意:给你一个字符串,然后再给你m个字符串,然后问你在第一个字符串中不连续的子串能不能构成输入的子串. 具体思路:构建一个序列自动机就可以了.刚接触,记录下 AC代码: #include<bits/stdc++.h> using namespace std; # define ll long long # define inf 0x3f3f3f3f ; ; char str[maxn]; ]; ]; void…
题目链接:https://ac.nowcoder.com/acm/contest/392/J 题目大意:给一个字符串s,然后在给出n个其他的字符串,判断每个字符串是否为s的子序列. 例: 输入: noiauwfaurainairtqltqlmomomo8rainairtqlnttxiaobaioiiioooorzcnzcnznbooooo 输出: YesYesYesYesNoYesNoNo 解题思路:序列自动机,对字符串s预处理出在每个位置,下一个字符出现的位置,匹配的时候就从前往后匹配,看是否…
咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\(s_i\)在S中的出现次数是\(cnt_i\),那么\(s_i\)对\(S\)的价值的贡献就是\(v_i*cnt_i\).因此,\(V_S=\Sigma_{i=1}^kcnt_i\times v_i\).求在区间\([l, r]\)中,有多少字符串的价值不超过k.\(\Sigma_{i=1}^n|s…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032 序列自动机其实就是每个位置记录一下某字母后面第一个出现位置,为了子序列能尽量长. 对字符串B建一个后缀自动机,一个序列自动机,然后让A在上面找即可: 1.枚举A每个位置开始的子串,在SAM上走,失配就找到了: 2.枚举A子串,用B的序列自动机找失配处: 3.设 f[i][j] 表示A串前 i 个字符形成的子序列对应SAM上节点 j 时的最短子序列长度,可以转移: 4.f[i][j]…
还以为序列自动机是什么,写完无意间看到帖子原来这就是序列自动机……这算自己发现算法…
题意 链接:https://vjudge.net/problem/HDU-6586 给你一个字符串和k,还有每个字符出现次数的限制,求一个长度为k的字典序最小的满足限制的子序列. 思路 先构造出序列自动机,顺带把num(i,j)(下标为i后面的字符为j的个数)求出来. 题目要求字典序最小,我们就贪心的对每一位每次从a~z枚举,check是否满足. check(x,y,t):第x位放字符y且第x-1位是原串的下标t所表示的字符.要满足以下几点: 用过的字符y的数量+1<=r[y] t后面要有j字符…
luoguP4112 [HEOI2015]最短不公共子串 链接 luogu loj 思路 子串可以用后缀自动机,子序列可以用序列自动机. 序列自动机是啥,就是能访问到所有子序列的自动机. 每个点记录下一个字母最近出现的位置.不过我这里构造是\(O(n^2)\). 然后进行bfs进行广搜就行了. 注意vis[][]剪枝,要不TLE. 代码 #include <bits/stdc++.h> #define ll long long using namespace std; const int N=…
[Codeforces 1201D]Treasure Hunting(DP) 题面 有一个n*m的方格,方格上有k个宝藏,一个人从(1,1)出发,可以向左或者向右走,但不能向下走.给出q个列,在这些列上可以向上走,其他列不能向上走.可以重复经过同一个点.求从(1,1)出发,经过所有宝藏的最短路径长度 \(n,m,k,q \leq 2 \times 10^5\) 分析 贪心考虑,我们应该按照行一层一层的走.每一行应该从最左的宝藏走到最右的宝藏,或者从最右的宝藏走到最左的宝藏,然后找最近的一个可以向…
正解:$dp$+$AC$自动机+搜索 解题报告: 传送门$QwQ$ 首先显然先建个$AC$自动机,然后考虑设$f_{i,j,k}$表示长度为$i$,现在在$AC$自动机的第$j$个位置,已经表示出来的串的状态为$k$的方案数,直接转移就好. 然后考虑输出方案.首先一定不存在可以随便填的位置. 挺显然的随便说下昂,首先如果有一个可以随便填的位置,就有26种可能.然后可以给这个位置和字符串交换位置,就至少有2种可能,这时候就已经至少有$2\times 26=52$了,所以一定不存在可以随便填的位置.…
序列自动机跑s串 假设k为s和t相同的长度,初始时相同长度为0 取s串中大于t[i]的最左边的位置,用n-tmp+1+i-1更新答案,tmp是最左端的位置 然后去t[i]相等的位置,走到下一位,如果下一位的位置不存在或者在tmp的右边,跳出循环即可. 最后就是s串中找出了一个和t串相同的串,之后的长度只要不为0,也是可以用来更新答案的. #include <bits/stdc++.h> using namespace std; const int maxn=1e6+10; const int…
题意:有一个模板串,有\(T\)个字符串,从字符串中找到某个子串,使得这个子串中的子序列包含模板串,求最短的子串的长度. 题解:找子序列,很容易想到序列自动机,根据序列自动机的原理,我们一定可以确保除了第一个字符,其他的字符的位置都是最优的,所以我们先对模板串的第一个字符\(p\)记录它的所有位置,然后再遍历它的位置,每次都跑一下序列自动机维护答案的最小值即可. 代码: const string p="puleyaknoi"; int t; string s; vector<in…
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ],t[]; int n,m; ][];//nex[i][j]表示i位置以字母j+'a'最先出现的位置 ][];//把t分割为t1和t2,dp[i][j]表示t1长度为i,t2长度为j时,在字符串s中的最小位置 int check(int x){ int y=m-x; dp[][]=; ;i<=x;++i) ;j<=y;++j){ &a…
题目大概是给几个DNA片段,求构造一个长度n的字符串的方案数,要求这个字符串每个位置的字符都属于某个包含于此字符串的DNA片段. 把那些DNA片段建一个AC自动机.考虑状态的表示: dp[len][x][k]表示长度len且后缀状态为自动机结点x且后k位还不满足要求的方案数 然后转移就是向自动机上四个方向的结点走,如果下一步结点x'是某DNA的后缀且长度比k大,那就是转移到dp[len+1][x'][0]否则转移到dp[len+1][x'][k+1].另外因为DNA最长10,所以第三维k不会超过…
题目链接: https://codeforces.com/contest/835/problem/D 题意: 一个回文串是\(1\)-回文的,如果一个回文串的左半部分和右半部分一样且都是\(k\)-回文串(右半部分是指长度为该串长度除以二下取整的后缀),则该串为\((k+1)\)回文串,满足该串是\(k\)回文串的最大\(k\)称作该串的回文级别.给定一个串\(s\), 对于每一个\(k=1,2,...,n\)求出该串中有多少个位置不同的\(k\)-回文串.\(n\le 5\times 10^6…
题目链接: https://codeforces.com/contest/1120/problem/C 题意: 从前往后压缩一段字符串 有两种操作: 1.对于单个字符,压缩它花费$a$ 2.对于末尾一段字符串,如果这段字符串是已经压缩过字符串的子串,那么可以选择压缩它,花费为$b$ 数据范围: $1\leq |S| \leq 5000$ $1\leq a \leq 5000$ $1\leq b \leq 5000$ 分析: 这道题目我们需要解决一个问题,计算某个子串出现的最早位置 转移,如果这个…