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;

 

转载于:https://www.cnblogs.com/oldjang/p/6525686.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值