笔记稍后补上,先看图
struct SAM{
int tot;
char str[MAXN];
int maxlen[MAXN],minlen[MAXN],trans[MAXN][26],slink[MAXN];
void init(){
tot=1;
maxlen[tot]=minlen[tot]=slink[tot]=0;
rep(i,0,25) trans[tot][i]=0;
}
int node(int mx,int mn,int from,int _slink){
++tot;
maxlen[tot]=mx;
minlen[tot]=mn;
slink[tot]=_slink;
rep(i,0,25) trans[tot][i]=trans[from][i];
return tot;
}
int add(char ch,int u){
int c=ch-'a',v=u;
int z=node(maxlen[u]+1,-1,0,0);
while(v&&trans[v][c]==0){
trans[v][c]=z;
v=slink[v];
}
if(v==0){
minlen[z]=1;
slink[z]=1;
return z;
}
int x=trans[v][c];
if(maxlen[v]+1==maxlen[x]){
minlen[z]=maxlen[x]+1;
slink[z]=x;
return z;
}
int y=node(maxlen[v]+1,-1,x,slink[x]);
slink[z]=slink[x]=y;
minlen[x]=minlen[z]=maxlen[y]+1;
while(v&&trans[v][c]==x){
trans[v][c]=y;
v=slink[v];
}
minlen[y]=maxlen[slink[y]]+1;
return z;
}
void build(){
int t=tot;
int len=strlen(str+1);
rep(i,1,len) t=add(str[i],t);
}
}sam;