https://wenku.baidu.com/view/ed1be61e10a6f524ccbf85fd.html
题意:求两个串的最长公共子串
思路:在求出height数组之后,再把sa数组区分出来,只要其中一个sa[i] (s[i -1])数组是属于第一串,s[i - 1] (s[i])属于第二串,那么我们可以求得其最大值,之所以可以这样做,是因为sa数组已经对字符串按字典序排好序了


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 2e6 + 5;
char s1[maxn], s2[maxn], s[maxn];
int n, p1, p2, m, p;
int tx[maxn], sa[maxn], rak[maxn];
int height[maxn];
struct node {
	int x, y, id;
}a[maxn], b[maxn];

void rsort() {
	for (int i = 1; i <= m; i++) {
		tx[i] = 0;
	}
	for (int i = 1; i <= n; i++) {
		tx[a[i].y]++;
	}
	for (int i = 1; i <= m; i++) {
		tx[i] += tx[i - 1];
	}
	for (int i = 1; i <= n; i++) {
		b[tx[a[i].y]--] = a[i];
	}
	for (int i = 1; i <= m; i++) {
		tx[i] = 0;
	}
	for (int i = 1; i <= n; i++) {
		tx[b[i].x]++;
	}
	for (int i = 1; i <= m; i++) {
		tx[i] += tx[i - 1];
	}
	for (int i = n; i >= 1; i--) {
		a[tx[b[i].x]--] = b[i];
	}
}

void solve() {
	rsort();
	p = 0;
	for (int i = 1; i <= n; i++) {
		if (a[i].x == a[i - 1].x && a[i].y == a[i - 1].y) {
			rak[a[i].id] = p;
		} else {
			rak[a[i].id] = ++p;
		}
	}
	for (int i = 1; i <= n; i++) {
		a[i].x = rak[i];
		a[i].id = sa[rak[i]] = i;
		a[i].y = 0;
	}
	m = p;
}
void ssort() {
	m = 127;
	for (int i = 1; i <= n; i++) {
		a[i].x = a[i].y = s[i];
		a[i].id = i;
	}
	solve();
	for (int j = 1; j <= n; j <<= 1) {
		for (int i = 1; i + j <= n; i++) {
			a[i].y = a[i + j].x;
		}
		solve();
		if (p == n) {
			break;
		}
	}
}	

void get_Height() {
	int k = 0;
	for (int i = 1; i <= n; i++) {
		if (k) {
			k--;
		}
		int j = sa[rak[i] - 1];
		while (s[i + k] == s[j + k]) {
			k++;
		}
		height[rak[i]] = k;
	}
}

int main() {
	scanf("%s", s1 + 1);
	scanf("%s", s2 + 1);
	p1 = strlen(s1 + 1);
	p2 = strlen(s2 + 1);
	for (int i = 1; i <= p1; i++) {
		s[++n] = s1[i];
	}
	s[++n] = '#';
	for (int i = 1; i <= p2; i++) {
		s[++n] = s2[i];
	}
	ssort();
	get_Height();
	int ans = 0;
	for (int i = 2; i <= n; i++) {
		if (height[i] > ans) {
			if ((sa[i] < p1 && sa[i - 1] > p1) || (sa[i] > p1 && sa[i - 1] < p1)) {
				ans = height[i];
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}