【hiho】127 后缀自动机一·基本概念 【后缀自动机】 hiho 大神 094791's beautiful Code

传送门:后缀自动机一·基本概念

后缀自动机(Suffix Automaton,简称SAM)是处理字符串的很强大的工具,对于一个字符串S,它对应的后缀自动机是一个最小的确定有限状态自动机(DFA),接受且只接受S的后缀。
对于字符串S="aabbabd",它的后缀自动机是:
【hiho】127 后缀自动机一·基本概念 【后缀自动机】
hiho 大神
094791's beautiful Code

介绍一个概念子串的结束位置集合 endpos。对于S的一个子串s,endpos(s) = s在S中所有出现的结束位置集合。还是以S="aabbabd"为例,endpos("ab") = {3, 6},因为"ab"一共出现了2次,结束位置分别是3和6。同理endpos("a") = {1, 2, 5}, endpos("abba") = {5}。

对于S="aabbabd":

状态 子串 endpos
S 空串 {0,1,2,3,4,5,6}
1 a {1,2,5}
2 aa {2}
3 aab {3}
4 aabb,abb,bb {4}
5 b {3,4,6}
6 aabba,abba,bba,ba {5}
7 aabbab,abbab,bbab,bab {6}
8 ab {3,6}
9 aabbabd,abbabd,bbabd,babd,abd,bd,d {7}

094791
van048
FakerInHeart

094791's beautiful Code

//后缀自动机一·基本概念
//hiho127
#include <bits/stdc++.h>
using namespace std;

void print(set<int>&s){
	set<int>::iterator it;
	for(it=s.begin();it!=s.end();it++){
		printf("%u ",*it);
	}
	putchar('
');
}
int main(){
	string s;
	map<string,set<int> >m;
	cin>>s;
	int i;
	int l;
	// 好优美!
	for(l=1;l<=s.length();l++){
		for(i=0;i+l<=s.length();i++){
			string sub=s.substr(i,l);
			set<int>tmp=m[sub];
			tmp.insert(i+l);
			m[sub]=tmp;
		}
	}
	int t;
	cin>>t;
	while(t--){
		cin>>s;
		string lstr=s;
		string sstr=s;
		set<int>tmp=m[s];
		map<string,set<int> >::iterator it;
		for(it=m.begin();it!=m.end();it++){
			if(it->second==tmp){
				if(lstr.length()<it->first.length()){
					lstr=it->first;
				}
				if(sstr.length()>it->first.length()){
					sstr=it->first;
				}
			}
		}
		printf("%s %s ",sstr.c_str(),lstr.c_str());
		print(tmp);
	}
    return 0;
}