后缀自动机模板

#include <bits/stdc++.h>

using namespace std;

#define ll long long

const int maxn = 1e6 + 5;

ll ans = 0;

namespace SAM {
	struct Node {
		int ch[26], fa, val;
		int len;
		Node(int len=0) : len(len), fa(-1), val(0) {
			memset(ch, 0, sizeof(ch));
		}
	} st[maxn << 1];
	int last, pt;
	void init() {
		st[last = pt = 0] = Node(0);
	}
	void extend(int v, int l) {
		int p = last, cur = ++pt;
		st[cur] = Node(l);
		st[cur].val = 1;
		for (; ~p && !st[p].ch[v]; p = st[p].fa) st[p].ch[v] = cur;
		if (p == -1) st[cur].fa = 0;
		else {
			int q = st[p].ch[v];
			if (st[p].len + 1 == st[q].len) st[cur].fa = q;
			else {
				int copy = ++pt;
				memcpy(&st[copy], &st[q], sizeof(Node));
				st[copy].len = st[p].len + 1;
				st[copy].val = 0;
				st[q].fa = copy;
				st[cur].fa = copy;
				for (; ~p && st[p].ch[v] == q; p = st[p].fa) st[p].ch[v] = copy;
			}
		}
		last = cur;
	}
	int d[maxn << 1], q[maxn << 1], s, t;
	void solve() {
		q[s = t = 0] = 0; d[0] = 1;
		for (register int i = 1; i <= pt; i++) d[st[i].fa]++;
		for (register int i = 0; i <= pt; i++) if (!d[i]) q[t++] = i;
		for (; s < t; ) {
			int u = q[s++];
			st[st[u].fa].val += st[u].val; 
			if (!--d[st[u].fa]) q[t++] = st[u].fa;
			if (st[u].val > 1) ans = max(ans, (ll)st[u].val * st[u].len);
		}
	}
}

char s[maxn];

int main() {
	freopen("ques.in", "r", stdin);
	freopen("ques.out", "w", stdout);
	scanf("%s", s);
	SAM::init();
	for (register int i = 0, end = strlen(s); i < end; i++)
		SAM::extend(s[i] - 'a', i+1);

	SAM::solve();

	printf("%lld", ans);

	return 0;
}
posted @ 2019-07-27 22:30  AC-Evil  阅读(132)  评论(1编辑  收藏  举报