bzoj 1301 后缀数组

  比较裸的后缀数组。

/**************************************************************
    Problem: 1031
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:808 ms
    Memory:5304 kb
****************************************************************/
 
//By BLADEVIL
var
    s, str                  :array[0..200010] of char;
    n, m, l                 :longint;
    i                       :longint;
    ws, wv                  :array[0..200010] of longint;
    w                       :array[0..200010,0..1] of longint;
    r, sa                   :array[0..200010] of longint;
      
procedure da;
var
    i, j, p, k1, k2         :longint;
begin
    for i:=0 to m do ws[i]:=0;
    for i:=0 to n do
    begin
        w[i][0]:=r[i];
        inc(ws[r[i]]);
    end;
    for i:=1 to m do inc(ws[i],ws[i-1]);
    for i:=n downto 0 do
    begin
        dec(ws[w[i][0]]);
        sa[ws[w[i][0]]]:=i;
    end;
     
    j:=1; p:=1;
    k1:=0; k2:=1;
    while p<=n do
    begin
        p:=0; i:=n-j+1;
        while i<=n do
        begin
            w[p][k2]:=i;
            inc(p);
            inc(i);
        end;
        for i:=0 to n do
            if sa[i]>=j then
            begin
                w[p][k2]:=sa[i]-j;
                inc(p);
            end;
         
        for i:=0 to n do wv[i]:=w[w[i][k2]][k1];
        for i:=0 to m do ws[i]:=0;
        for i:=0 to n do inc(ws[wv[i]]);
        for i:=1 to m do inc(ws[i],ws[i-1]);
        for i:=n downto 0 do
        begin
            dec(ws[wv[i]]);
            sa[ws[wv[i]]]:=w[i][k2];
        end;
         
        k1:=k1 xor 1; 
        k2:=k2 xor 1;
        p:=1;
        w[sa[0]][k1]:=0;
        for i:=1 to n do
        begin
            if (w[sa[i-1]][k2]=w[sa[i]][k2]) and (w[sa[i-1]+j][k2]=w[sa[i]+j][k2]) then
                w[sa[i]][k1]:=p-1 else
                begin
                    w[sa[i]][k1]:=p;
                    inc(p);
                end;
        end;
        j:=j<<1; m:=p;
    end;
      
end;
      
begin
    n:=0;
    while not eoln do
    begin
        read(str[n]);
        inc(n);
    end;
    l:=n; dec(n);
    s:=str;
    for i:=n+1 to 2*n+1 do s[i]:=str[i-n-1];
    n:=2*n+2;
    s[n]:=chr(1);
    for i:=0 to n do
    begin
        r[i]:=ord(s[i]);
        if r[i]>m then m:=r[i];
    end;
    da;
    for i:=0 to n do
        if sa[i]<l then write(s[sa[i]+l-1]);
    writeln;
end.
 

 

posted on 2014-01-23 17:10  BLADEVIL  阅读(381)  评论(0编辑  收藏  举报