![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
字符串
文章平均质量分 54
hungry1234
这个作者很懒,什么都没留下…
展开
-
广义SAM(SAM套trie)
SAM是处理单个字符串的首选算法,若是多个字符串但是又符合SAM出题的题型,考虑广义SAM 1.伪广义SAM 大概有两种做法 1.在各个字符串中间加上一些奇怪的字符(或者让last变成初始点),然后按照普通SAM做即可 2.对一个字符串构建SAM(一般选最短的),然后用其他的字符串去在这个SAM上跑,打上标记后经过一系列操作去得到正确答案 [HAOI2016]找相同字符 并没有想到用广义SAM怎么做 考了对一个串建立SAM 对于另一个串,在SAM上跑,维护当前最长子串,因为相当于长度为1~最原创 2022-01-14 23:35:10 · 596 阅读 · 0 评论 -
字符串hash
1.用途:判断两个字符串是否相同 2.原理:将一个字符串转换成一个多项式(或者说是n进制数),将字符串映射到整数域,比较字符串就是比较数字 3.实现: 1.确定数字的进制与模数(一般模数都是一个大质数) 2.将一个字符串按照数字计算转化为一个数字 typedef unsigned long long ull; ull base=233ull,mod=1e9+7ull; ull hash(char *s){ ull p=0; for(int i=1;i<=strlen(s);i++){原创 2021-08-09 17:32:37 · 151 阅读 · 0 评论 -
AC自动机
1.应用:用于多个模式串与一个文本串的匹配问题 2.原理:将模式串建立trie树,运用kmp的思想匹配文本串 3.基础操作: 1.insert(同trie树) void insert(char *s,int l,int x){ int p=0; for(int i=0;i<l;i++){ int ty=s[i]-'a'; if(!dic[p][ty]) dic[p][ty]=++num; p=dic[p][ty]; } id[p].push_back(x);原创 2021-08-05 22:48:59 · 53 阅读 · 0 评论 -
kmp&trie
kmp: 1.前缀数组:kmp[i]:指在s[1]-s[i]所组成的字符串的前缀和后缀相等的长度 令j=kmp[i-1],已知1~j与i-1-j~i-1相等,若s[i]==s[j+1],则易得kmp[i]==kmp[i-1]+1; 否则令j=kmp[kmp[i-1]], 重复以上操作,若j==0,则说明字符串s[1]~s[i]中前缀和后缀没有相等的 在O(n)的时间内可以求出: int kmp[500010]; char s[500010]; kmp[0]=kmp[1]=0; int j=.原创 2021-08-04 22:42:32 · 118 阅读 · 0 评论 -
SAM的构造
sam实质:将一个字符串高度压缩后的后缀放入一个自动机内,使得这个自动机可以接受所有文本的字串 endpos:字串末尾在原串中出现位置的集合 parent tree:若一个节点的endpos是另一个的子集,那么parent tree有一条由母集到子集的边 自动机中,每个状态代表的是endpos集合相等的一些字符串 添加字符是分三种情况 令未加入这个字符的为原串,las为原串所在节点 1.没有这个字符:las所在链上所有点向新节点连边 2.若有 2.1.若本来这个字符和原串...原创 2022-01-12 23:36:34 · 237 阅读 · 0 评论 -
字符串杂项
两个不怎么常见的算法 1.Z函数 定义:z[i]表示以i开头的后缀与整个串最长的公共串长度 求法:假设i以前的字符串已经求完,记录l,r为右端最大的区间 [i,i+z[i]-1] 若 i<r ,则根据定义,z[i]=z[i-l] 但是i-l>r的情况下不能保证正确性,需要暴力判断 否则就暴力求出z函数值 用处(其实kmp都可以实现,只不过有些用z函数更直观) 1.匹配字符串 对于两个字符串跑z函数的过程,若z函数值...原创 2022-01-11 22:26:51 · 262 阅读 · 0 评论 -
SAM经典用法
1.判断字符串出现次数 SAM中,每个节点代表的是endpos集合相同的一些状态 endpos是字串末尾的集合,故endpos的大小就是出现次数 考虑求出endpos集合大小 对于parent tree上的一个节点,他的子节点每出现一次,这个点就会相应的出现一次(因为这个点一定是他的子节点的子串) 故每个点出现次数是它的子节点出现次数和+1(+1这个节点所代表字符串本身出现的第一次) void dfs(int x){ for(int i=0;i<tu[x].size();i++){原创 2022-01-13 23:23:35 · 2142 阅读 · 0 评论