zoukankan      html  css  js  c++  java
  • 【模板】后缀自动机

    后缀自动机是一个能够接受母串所有后缀的最简自动机。
    其中,每个节点代表一个字符串集合,该集合中所有的字符串均有相同的 (right) 集合。
    各个节点之间根据 (right) 集合的关系可以组织成一棵树形结构,称为 (parent) 树。
    后缀自动机最多有 (2*n - 1) 个节点。

    代码如下

    #include <bits/stdc++.h>
    
    using namespace std;
    
    struct SAM {
    	struct state {
    		int len, p, cnt;
    		map<char, int> go;
    		state(int _len = 0, int _p = -1, int _cnt = 0) {
    			len = _len;
    			p = _p;
    			cnt = _cnt;
    		}
    	};
    	int last;
    	vector<state> t;
    	SAM() {
    		last = 0;
    		t.push_back({});
    	}
    	inline state& operator[](int x) {
    		return t[x];
    	}
    	inline int size() {
    		return t.size();
    	}
    	inline void extend(char c) {
    		int cur = t.size();
    		t.push_back({t[last].len + 1, -1, 1});
    		int x = last;
    		while (x != -1 && t[x].go.count(c) == 0) {
    			t[x].go[c] = cur;
    			x = t[x].p;
    		}
    		if (x == -1) {
    			t[cur].p = 0;
    		} else {
    			int y = t[x].go[c];
    			if (t[y].len == t[x].len + 1) {
    				t[cur].p = y;
    			} else {
    				int z = t.size();
    				t.push_back(t[y]);
    				t[z].len = t[x].len + 1;
    				t[z].cnt = 0;
    				while (x != -1 && t[x].go[c] == y) {
    					t[x].go[c] = z;
    					x = t[x].p;
    				}
    				t[cur].p = t[y].p = z;
    			}
    		}
    		last = cur;
    	}
    };
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0), cout.tie(0);
    	int n;
    	string s;
    	cin >> s;
    	n = s.size();
    	SAM sam;
    	for (int i = 0; i < n; i++) {
    		sam.extend(s[i]);
    	}
    	vector<vector<int>> adj(sam.size());
    	for (int i = sam.size() - 1; i >= 1; i--) {
    		adj[sam[i].p].push_back(i);
    	}
    	long long ans = 0;
    	function<void(int)> dfs = [&](int u) {
    		for (auto v : adj[u]) {
    			dfs(v);
    			sam[u].cnt += sam[v].cnt;
    		}
    		if (sam[u].cnt > 1) {
    			ans = max(ans, (long long)sam[u].cnt * sam[u].len);
    		}
    	};
    	dfs(0);
    	cout << ans << endl;
    	return 0;
    } 
    
  • 相关阅读:
    python | if else || where true 流程控制
    python |生成器
    python| 什么是迭代器?
    Python -WordCloud安装、词云制作
    技巧 |Python 使用dict.fromkeys()快速生成一个字典
    python 列表(list)去重方法总结
    区别 |python 的read、readline、readlines和write、writelines
    区别 |Python的 open() 和with open() as
    散点图和气泡图的几种制作方法
    宽表和窄表的建设该如何选择?
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/11586525.html
Copyright © 2011-2022 走看看