后缀数组板子
来源:互联网 发布:php httpclient 类库 编辑:程序博客网 时间:2024/06/13 07:18
// SA[i] = j表示为按照从小到大排名为i的后缀 是以j(下标)开头的后缀//rank[i] = j 表示为按照从小到大排名 以i为下标开始的后缀 排名为j//height数组:定义height[i]=suffix(sa[i-1])和suffix(sa[i])的最长公共前缀#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#include<string>using namespace std;const int maxn =2e4+10;int vis[maxn];int q[maxn];struct Suffix{ int s[maxn]; int SA[maxn],ranked[maxn],height[maxn]; int x[maxn],y[maxn],buc[maxn],len,m; void init(int *str) { len=strlen(str); for(int i=0;i<len;i++) s[i]=(int)str[i]; m=2e4+10;//m为str中最大的数 } void GetSA() { for (int i = 0; i < m; i++) buc[i] = 0; // buc 是一个桶 for (int i = 0; i < len; i++) buc[x[i] = s[i]]++; for (int i = 1; i < m; i++) buc[i] += buc[i - 1]; for (int i = len - 1; i >= 0; i--) SA[--buc[x[i]]] = i; for (int k = 1; k <= len; k <<= 1) { // k 倍增 int p = 0; //对第二关键字排序,y[i]:第i大的第二关键字是谁 // 后缀 len - k 及之后的所有后缀第二关键字最小。为0 for (int i = len - 1; i >= len - k; i--) y[p++] = i; for (int i = 0; i < len; i++) if (SA[i] >= k) y[p++] = SA[i] - k; //总体来排个序,求出SA for (int i = 0; i < m; i++) buc[i] = 0; for (int i = 0; i < len; i++) buc[x[y[i]]]++; for (int i = 1; i < m; i++) buc[i] += buc[i - 1]; for (int i = len - 1; i >= 0; i--) SA[--buc[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[SA[0]] = 0; // 重新计算每个一元的名次。则x数组里存的是总体的顺序 for (int i = 1; i < len; i++) { if (y[SA[i - 1]] == y[SA[i]] && y[SA[i - 1] + k] == y[SA[i] + k]) x[SA[i]] = p - 1; else x[SA[i]] = p++; } if (p >= len) break; // 每个后缀的名次已经完全不同,不需要继续倍增 m = p; // 更新名次的最大值。 } } void Getheight() { for(int i=0;i<len;i++) ranked[SA[i]]=i; int k=0; for(int i=0;i<len;i++) { if(ranked[i]==0) {height[0]=0;continue;} if(k) k--; int j=SA[ranked[i]-1]; while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++; height[ranked[i]]=k; } } int LCS(char *s1)//求两个字符串的最大公共子串 { int l=strlen(s1); s1[l]=' '; scanf("%s",s1+l+1); init(s1); build(); LCP(); int ans=0; for(int i=1;i<len;i++) if((SA[i-1]<l&&SA[i]>l)||(SA[i-1]>l&&SA[i]<l)) ans=max(ans,height[i]); return ans; }};Suffix a;string str1;string str2;char str[maxn];int main(){ while(scanf("%s",str)!=EOF){ printf("%d\n",a.LCS(str)); } return 0;}
阅读全文
0 0
- 后缀数组板子
- 后缀数组板子
- 后缀数组板子
- 重复次数最多的连续字串 后缀数组板子 黑盒子
- poj 2406 后缀数组dc3 板子 计算出现次数最多的循环节 dc3 板子
- 重复旋律 后缀数组 板子 最长可重叠重复子串问题
- POJ 2406 Power Strings(KMP or 后缀数组 dc3板子)
- 树状数组板子
- 【板子】树状数组
- 后缀树/后缀数组
- 后缀树 后缀数组
- 【后缀数组】后缀排序
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- JAVA导出报表 ExportExcel 1
- pip安装 管理软件
- SparkContext解密
- SpringMVC深度探险(二) —— SpringMVC概览(转)
- java实现生产者和消费者问题的几种方式
- 后缀数组板子
- 树的先序遍历
- sdut 3923 打字
- linux命令之more
- GPRS+wifi 云巡更系统开放sdk api 可以和OA CRM 对接巡更系统
- gdb调试多进程多线程
- phantomjs入门学习笔记之一
- java利用CXF实现WebService 实例
- h2db数据库初使用