题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走法,即把 DAG 上自己能走到的点的 right 都收集起来,可用拓扑序解决. 相同子串算一个的话,给 DAG 上每个节点都赋上一个1,表示走到那个节点的话算一个子串:然后把 DAG 上自己能走到的点的1都收集起来. 然后可按字典序 dfs 这个 DAG ,如果 k 在这个分支里的话就走进去,否则…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 关于相同子串算一个还是算多个,其实就是看一种状态的 right 集合是否加上 Parent 树中子树的 right 集合: 虽然是子串却不管 l 数组,因为实际上 dfs 走到一个点,得到的是一个确定的子串,而这个子串的状态属于这个点表示的状态,l 数组是这个点表示的状态数,当然不用考虑: 记一个 sum 表示这个状态往后加字母能得到的所有子串个数,然后在SAM上按字典序 dfs ,…
SA的话t==0直接预处理出每个后缀的不同串贡献二分即可,然后t==1就按字典序枚举后缀,然后跳右端点计算和当前后缀的前缀相同的子串个数,直到第k个 不过bzoj上会T #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=10000005; int n,o,sa[N],rk[N],he[N],wa[N],wb[N],wsu[N],wv[N],st[2…