后缀数组模板(别看了,看不懂的)

放肆的年华 提交于 2019-11-27 00:33:50
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <iostream>
// #include <ctime>
// #include <cmath>
// #include <map>
// #include <vector>
// #include <set>
#include <string>

#define open_in(x) freopen(""#x".in","r",stdin)
#define open_out(x) freopen(""#x".out","w",stdout)
#define open_(x) freopen(""#x".in","w",stdout)
#define open(x) open_in(x); open_out(x)
#define mes(x, y) memset(x, y, sizeof(x))
#define mec(x, y) memcpy(x, y, sizeof(x))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int X = 200010;
const int M = 1e9+7;

// inline int Random(int a,int b) {return rand() % (b - a + 1) + a;}

template<class T>
inline T read(T &x) {
	int f = 1;char ch = getchar();x = 0;
	while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
	return x *= f;
}

int n, m, sa[X], rak[X], tmp[X], buk[X], height[X];
string str;

// int ans = 0;

void Sort() {
	for (int i = 1; i <= m; i++) buk[i] = 0;
	for (int i = 1; i <= n; i++) buk[rak[i]]++;
	for (int i = 1; i <= m; i++) buk[i] += buk[i - 1];
	for (int i = n; i >= 1; i--) sa[buk[rak[tmp[i]]]--] = tmp[i];
}

int main() {
	open_in(SA);
	read(n);
	cin >> str;
	str = ' ' + str;
	for (int i = 1; i <= n; i++) {
		m = max(m, rak[i] = str[i] - 'a' + 1);
		tmp[i] = i;
	}
	Sort();
	for (int p = 0, k = 1; p < n; k <<= 1, m = p) {
		p = 0;
		for (int i = 1; i <= k; i++) tmp[++p] = n - k + i;
		for (int i = 1; i <= n; i++)
			if (sa[i] > k)
				tmp[++p] = sa[i] - k;
		Sort();
		swap(rak, tmp);
		rak[sa[1]] = p = 1;
		for (int i = 2; i <= n; i++)
			rak[sa[i]] = (tmp[sa[i]] == tmp[sa[i-1]] && tmp[sa[i] + k] == tmp[sa[i - 1] + k] ? p : ++p);
	}

	for (int i = 1, Max = 0; i <= n; i++) {
		Max = max(Max - 1, 0);
		while (str[i + Max] == str[sa[rak[i] - 1] + Max]) Max++;
		height[rak[i]] = Max;
	}

	/*for (int i = 1; i <= n; i++)
		ans = max(ans, height[rak[i]]);

	printf("%d\n", ans);*/
	return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!