hihocoder-1415 后缀数组三·重复旋律3 两个字符串的最长公共子串

把s1,s2拼接,求Height。相邻的Height判断左右串起点是否在两个串中,另外对Height和s1.length()-SA[i-1]取min。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#include <stdlib.h>
#include <time.h>
#define LL long long
using namespace std;
const LL mod = ;
const LL N = ;
int s1l, s2l;
class SF
{
//N:数组大小
public:
int x[N], y[N], c[N];
int Height[N],str[N], SA[N], Rank[N];//Height数组从2开始
int slen;
int m=;//字符集处理大小(传入如果不是数字,需要做位移转换)
bool cmp(int* r, int a, int b, int l) {
return r[a] == r[b] && r[a + l] == r[b + l];
} void Suffix(int n) {
++n;
int i, j, p;
for (i = ; i < m; ++i) c[i] = ;
for (i = ; i < n; ++i) c[x[i] = str[i]]++;
for (i = ; i < m; ++i) c[i] += c[i - ];
for (i = n - ; i >= ; --i) SA[--c[x[i]]] = i;
for (j = ; j <= n; j <<= ) {
p = ;
for (i = n - j; i < n; ++i) y[p++] = i;
for (i = ; i < n; ++i) if (SA[i] >= j) y[p++] = SA[i] - j;
for (i = ; i < m; ++i) c[i] = ;
for (i = ; i < n; ++i) c[x[y[i]]]++; for (i = ; i < m; ++i) c[i] += c[i - ];
for (i = n - ; i >= ; --i) SA[--c[x[y[i]]]] = y[i]; swap(x, y);
p = ; x[SA[]] = ;
for (i = ; i < n; ++i) {
x[SA[i]] = cmp(y, SA[i - ], SA[i], j) ? p - : p++;
}
if (p >= n)break;
m = p;
} int k = ;
n--;
for (i = ; i <= n; ++i) Rank[SA[i]] = i;
for (i = ; i < n; ++i) {
if (k)--k;
j = SA[Rank[i] - ];
while (str[i + k] == str[j + k])++k;
Height[Rank[i]] = k;
//cout << k << endl;
}
}
void init(string s)//不论什么参数,用引用传入
{
slen = s.length();
for (int i = ; i < slen; i++)
str[i] =s[i]-'a'+;//如果是字符,映射成从1开始的序列
str[slen] = ;//0作为结束符,防止越界
Suffix(slen);
}
LL solve()
{
int ans = ;
for (int i = ; i <= slen; i++)
{
int sa1 = SA[i - ],sa2=SA[i];
if (sa1 > sa2) swap(sa1, sa2);
if (sa1 >= s1l || sa2 < s1l) continue;
ans = max(ans, min(s1l - sa1, Height[i]));
}
return ans;
}
}sf;
LL dp[][];
LL n;
int main() {
cin.sync_with_stdio(false);
string s1,s2;
while (cin >> s1>>s2)
{
s1l = s1.length();
s2l = s2.length();
sf.init(s1+s2);
cout << sf.solve() << endl;
}
return ;
}
上一篇:linux USR1亦通常被用来告知应用程序重载配置文件


下一篇:Python 基础【第一篇】环境部署