SAM板子
function newnode(x:longint):longint; begin inc(cnt);dis[cnt]:=x;exit(cnt); end; procedure add(id:longint); var ch,i:char;p,np,q,nq,j:longint; begin ch:=s[id];np:=newnode(id);p:=last;last:=np; while(p>0)and(t[p].son[ch]=0)do begin t[p].son[ch]:=np;p:=t[p].fa; end; if p=0 then t[np].fa:=root else begin q:=t[p].son[ch]; if dis[q]=dis[p]+1 then t[np].fa:=q else begin nq:=newnode(dis[p]+1); for i:='a' to 'z' do t[nq].son[i]:=t[q].son[i]; t[nq].fa:=t[q].fa; t[q].fa:=nq;t[np].fa:=nq; while t[p].son[ch]=q do begin t[p].son[ch]:=nq;p:=t[p].fa; end; end; end; end; procedure build; var i,len:longint; begin readln(s);len:=length(s); cnt:=1;root:=1;last:=1; for i:=1 to len do add(i); for i:=1 to cnt do inc(sum[dis[i]]); for i:=1 to len do inc(sum[i],sum[i-1]); for i:=cnt downto 1 do begin tmp[sum[dis[i]]]:=i;dec(sum[dis[i]]); end; end;