const int maxn = 112345 ,mlen = 26;
struct Sam{
int len[maxn*2],fa[maxn*2],nex[maxn*2][mlen];
int _cnt,root,omg;
int newNode(int L = 0){
len[_cnt] = L;
memset(nex[_cnt],fa[_cnt] = -1,sizeof(nex[_cnt]));
return _cnt++;
}
void init(){
_cnt = 0;
root = omg = newNode();
}
void extend(int x){
int ox = newNode(len[omg]+1);
while(omg != -1 && nex[omg][x] == -1){
nex[omg][x] = ox;
omg = fa[omg];
}
if(omg == -1) fa[ox] = root;
else{
int omgx = nex[omg][x];
if(len[omgx] == len[omg]+1) fa[ox] = omgx;
else{
int mgx = newNode(len[omg]+1);
for(int i=0;i<mlen;i++)
nex[mgx][i] = nex[omgx][i];
fa[mgx] = fa[omgx];
fa[omgx] = fa[ox] = mgx;
while(omg != -1 && nex[omg][x] == omgx)
nex[omg][x] = mgx,omg = fa[omg];
}
}
omg = ox;
}
void build(char *arr){
init();
for(int i=0;arr[i];i++){
extend(arr[i] - 'a');
}
}
void run(char *arr){
int st = root,lens = 0;
for(int i = 0;arr[i];i++){
int x = arr[i] - 'a';
if(nex[st][x] != -1){
st = nex[st][x];
lens++;
}
else{
while(st != -1 && nex[st][x] == -1)
st = fa[st];
if(st == -1){
st = root;
lens = 0;
}
else{
lens = len[st]+1;
st = nex[st][x];
}
}
//update maxlen
}
}
}SAM;
/-------------
const int maxn = 112345,maxLen = 130;
int toid(char c){ return c; }
queue<int> Q;
struct acam{
int nex[maxn][maxLen],fail[maxn];
int cnt[maxn];
int _cnt,root;
int newNode(){
memset(nex[_cnt],fail[_cnt] = -1,sizeof(nex[_cnt]));
cnt[_cnt] = 0;
return _cnt++;
}
void init(){
_cnt = 0;
root = newNode();
}
void insert(char *arr,int id){
int st = root;
for(int i=0;arr[i];i++){
int & stx = nex[st][toid(arr[i])];
if(stx == -1) stx = newNode();
st = stx;
}
cnt[st]++;
// update cnt
}
void build(){
while(Q.empty()==false) Q.pop();
fail[root] = root;
int st;
for(int i=0;i<maxLen;i++){
if((st = nex[root][i]) != -1){
fail[st] = root;
Q.push(st);
}
else nex[root][i] = root;
}
while(Q.empty()==false){
st = Q.front(),Q.pop();
for(int i=0;i<maxLen;i++){
if(nex[st][i] != -1){
int fst = fail[st],son = nex[st][i];
while(fst != root && nex[fst][i] == -1)
fst = fail[fst];
fail[son] = nex[fst][i] == -1 ? root : nex[fst][i];
Q.push(son);
}
else{
nex[st][i] = nex[fail[st]][i];
}
}
};
}
int cal(char *arr){
int st = root;
for(int i=0;arr[i];i++){
st = nex[st][toid(arr[i])];
int tem = st;
while(tem != root){
// cal something
tem = fail[tem];
}
}
// return something
}
}acam;
Sam后缀自动机模板
最新推荐文章于 2022-11-25 16:02:35 发布