poj 2774 Long Long Message 后缀数组
2016-01-04 12:32
267 查看
题目链接
求两个字符串的最长公共子串。
将两个字符串连接起来, 然后找height的最大值, 还要注意此时的sa[i]和sa[i-1]不能在同一个串中。
求两个字符串的最长公共子串。
将两个字符串连接起来, 然后找height的最大值, 还要注意此时的sa[i]和sa[i-1]不能在同一个串中。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 2e5+5; int sa[maxn]; int t1[maxn],t2[maxn],c[maxn], a[maxn]; int rankk[maxn],height[maxn]; void build_sa(int s[],int n,int m) { int i,j,p,*x=t1,*y=t2; for(i=0;i<m;i++)c[i]=0; for(i=0;i<n;i++)c[x[i]=s[i]]++; for(i=1;i<m;i++)c[i]+=c[i-1]; for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i; for(j=1;j<=n;j<<=1) { p=0; for(i=n-j;i<n;i++)y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; for(i=0;i<m;i++)c[i]=0; for(i=0;i<n;i++)c[x[y[i]]]++; for(i=1;i<m;i++)c[i]+=c[i-1]; for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; if(p>=n)break; m=p; } } void getHeight(int s[],int n) { int i,j,k=0; for(i=0;i<=n;i++)rankk[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rankk[i]-1]; while(s[i+k]==s[j+k])k++; height[rankk[i]]=k; } } int main() { int n, m, t; string s, str; cin>>s>>str; n = s.size(); for(int i = 0; i<n; i++) { a[i] = s[i]-'a'; } a = 27; for(int i = 0; i<str.size(); i++) { a[i+n+1] = str[i]-'a'; } build_sa(a, n+1+str.size()+1, 28); getHeight(a, n+1+str.size()); int maxx = 0; for(int i = 2; i<=n+1+str.size(); i++) { if(height[i]>maxx) { if(sa[i-1]<n&&sa[i]>n) maxx = height[i]; if(sa[i]<n&&sa[i-1]>n) maxx = height[i]; } } cout<<maxx<<endl; return 0; }
相关文章推荐
- CF Good Bye 2015 E. New Year and Three Musketeers(贪心+枚举)
- ImportError: No module named cv2
- iOS中UITableView性能优化
- Socket编程实践(7) --Socket-Class封装(改进版v2)
- 小木木的Python学习笔记
- android 使用字体图标(Icon Font)
- 使用MDK将STM32的标准库编译成lib使用
- Socket编程实践(6) --TCP服务端注意事项
- 根据Html文本设置控件的尺寸
- 应用时代,firefox os之死
- Socket编程实践(5) --TCP粘包问题与解决
- android开发笔记:framgment相关
- Leetcode-25.Reverse Nodes in k-Group
- android 自定义控件之圆形菜单
- Socket编程实践(4) --多进程并发server
- uva 10082 - WERTYU
- Java多线程碎碎念
- Python学习笔记(2)
- LeetCode 008 String to Integer (atoi)
- HDU 5002 Tree