后缀数组模板

P

uses math;
var
        sg:ansistring;
        s:array[0..100000]of char;
        i,n,x,g,l,j,p,h,ma,t1,t2,ans:longint;
        w,v,y,ss,r,wa,ex,z,o:array[0..200000]of longint;
        a:array[0..100000,1..2]of longint;
        rank,sa,height,f:array[0..100000]of longint;
begin
        readln(n);
        readln(sg);
        for i:=0 to n-1 do
                s[i]:=sg[i+1];
        for i:=0 to n-1 do
                r[i]:=ord(s[i]);
        ma:=130;
        fillchar(w,sizeof(w),0);
        g:=0;
        l:=0;
        for i:=0 to n do
        begin
                wa[i]:=r[i];
                inc(w[wa[i]]);
        end;
        for i:=1 to ma-1 do
                inc(w[i],w[i-1]);
        for i:=n downto 0 do
        begin
                dec(w[wa[i]]);
                sa[w[wa[i]]]:=i;
        end;
        i:=1;
        p:=1;
        while p<n+1 do
        begin
                p:=0;
                j:=n-i+1;
                while j<n+1 do
                begin
                        y[p]:=j;
                        inc(p);
                        inc(j);
                end;
                for j:=0 to n do
                        if sa[j]>=i then
                        begin
                                y[p]:=sa[j]-i;
                                inc(p);
                        end;
                for j:=0 to n do
                        v[j]:=wa[y[j]];
                fillchar(w,sizeof(w),0);
                for j:=0 to n do
                        inc(w[v[j]]);
                for j:=1 to ma-1 do
                        inc(w[j],w[j-1]);
                for j:=n downto 0 do
                begin
                        dec(w[v[j]]);
                        sa[w[v[j]]]:=y[j];
                end;
                ss:=wa;
                wa:=y;
                y:=ss;
                p:=1;
                wa[sa[0]]:=0;
                for j:=1 to n do
                        if (y[sa[j-1]]=y[sa[j]])and(y[sa[j-1]+i]=y[sa[j]+i]) then
                                wa[sa[j]]:=p-1
                        else
                        begin
                                wa[sa[j]]:=p;
                                inc(p);
                        end;
                i:=i*2;
                ma:=p;
        end;
        for i:=1 to n do
                rank[sa[i]]:=i;
        h:=0;
        for i:=0 to n-1 do
        begin
                if h>0 then
                        dec(h)
                else
                        h:=0;
                j:=sa[rank[i]-1];
                while r[j+h]=r[i+h] do
                        inc(h);
                height[rank[i]]:=h;
        end;
        for i:=n downto 1 do
        begin
                inc(sa[i]);
                rank[i]:=rank[i-1];
        end;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值