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.

 

 

你可能感兴趣的:(后缀数组)