两串相接
先判断sa[i]与sa[i-1]属于不同串 再取height[i] 的最值
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include <deque>
#include <set>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
typedef long long LL;
const int INF = 1<<29;
const int mod = 2552 ;
const int MAXN = 210000;
int t1[MAXN],t2[MAXN],c[MAXN]; //求SA数组需要的中间变量,不需要赋值
//待排序的字符串放在s数组中,从s[0] 到s[n-1], 长度为n, 且最大值小于m,
//除s[n-1] 外的所有s[i] 都大于0, r[n-1]=0
//函数结束以后结果放在sa数组中
bool cmp(int *r, int a, int b, int l)
{
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int str[], int sa[], int rank[], int height[], int n, int m)
{
n++;
int i, j, p, *x = t1, *y = t2;
//第一轮基数排序,如果s的最大值很大,可改为快速排序
for(i = 0; i < m; i++)c[i] = 0;
for(i = 0; i < n; i++)c[x[i] = str[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;
//直接利用sa数组排序第二关键字
for(i = n-j; i < n; i++)y[p++] = i; //后面的j 个数第二关键字为空的最小
for(i = 0; i < n; i++) if(sa[i] >= j)y[p++] = sa[i] - j;
//这样数组y保存的就是按照第二关键字排序的结果
//基数排序第一关键字
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];
//根据sa和x数组计算新的x数组
swap(x,y);
p = 1;
x[sa[0]] = 0;
for(i = 1; i < n; i++)
x[sa[i]] = cmp(y,sa[i -1],sa[i],j)?p- 1:p++;
if(p >= n) break;
m = p; //下次基数排序的最大值
}
int k = 0;
n--;
for(i = 0; i <= n; i++)rank[sa[i]] = i;
for(i = 0; i < n; i++)
{
if(k)k--;
j = sa[rank[i] -1];
while(str[i+k] == str[j+k])k++;
height[rank[i]] = k;
}
}
int rank[MAXN],height[MAXN];
char str[MAXN],st[MAXN];
int r[MAXN];
int sa[MAXN];
int solve(int x,int len1,int len2)
{
if(sa[x]<=len1&&sa[x-1]>len1)
return 1;
if(sa[x-1]<=len1&&sa[x]>len1)
return 1;
return 0;
}
int main()
{
scanf("%s%s",str,st);
int n;
int len1=strlen(str);
int len2=strlen(st);
for(n=0;str[n];n++)
r[n]=str[n];
r[n++]=0;
for(int i=0;st[i];i++)
r[n++]=st[i];
da(r,sa,rank,height,n,128);
int ans=0;
for(int i=2;i<=n;i++)
if(height[i]>ans&&solve(i,len1,len2))
ans=height[i];
cout<<ans<<endl;
return 0;
}