SPOJ694&705Distinct Substrings(后缀数组)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ694&705Distinct Substrings(后缀数组)相关的知识,希望对你有一定的参考价值。
题意:求一个字符串的不相同的子串个数
n<=1000
思路:这是一道论文题
1 var a,x,y,sa,rank,height,wc,wd:array[0..3000]of longint; 2 n,i,m,ans,v,cas:longint; 3 ch:ansistring; 4 5 procedure swap(var x,y:longint); 6 var t:longint; 7 begin 8 t:=x; x:=y; y:=t; 9 end; 10 11 function cmp(a,b,l:longint):boolean; 12 begin 13 exit((y[a]=y[b])and(y[a+l]=y[b+l])); 14 end; 15 16 procedure getsa(n:longint); 17 var i,j,p:longint; 18 begin 19 for i:=0 to n-1 do 20 begin 21 x[i]:=a[i]; 22 inc(wc[a[i]]); 23 end; 24 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 25 for i:=n-1 downto 0 do 26 begin 27 dec(wc[x[i]]); 28 sa[wc[x[i]]]:=i; 29 end; 30 j:=1; p:=1; 31 while p<n do 32 begin 33 p:=0; 34 for i:=n-j to n-1 do 35 begin 36 y[p]:=i; inc(p); 37 end; 38 for i:=0 to n-1 do 39 if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end; 40 for i:=0 to n-1 do wd[i]:=x[y[i]]; 41 for i:=0 to m-1 do wc[i]:=0; 42 for i:=0 to n-1 do inc(wc[wd[i]]); 43 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 44 for i:=n-1 downto 0 do 45 begin 46 dec(wc[wd[i]]); 47 sa[wc[wd[i]]]:=y[i]; 48 end; 49 for i:=0 to n do swap(x[i],y[i]); 50 p:=1; x[sa[0]]:=0; 51 for i:=1 to n-1 do 52 if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1 53 else begin x[sa[i]]:=p; inc(p); end; 54 j:=j*2; 55 m:=p; 56 end; 57 end; 58 59 procedure getheight(n:longint); 60 var i,j,k:longint; 61 begin 62 k:=0; 63 for i:=1 to n do rank[sa[i]]:=i; 64 for i:=0 to n-1 do 65 begin 66 if k>0 then dec(k); 67 j:=sa[rank[i]-1]; 68 while a[i+k]=a[j+k] do inc(k); 69 height[rank[i]]:=k; 70 end; 71 end; 72 73 begin 74 assign(input,\'spoj694.in\'); reset(input); 75 assign(output,\'spoj694.out\'); rewrite(output); 76 readln(cas); 77 for v:=1 to cas do 78 begin 79 fillchar(a,sizeof(a),0); 80 fillchar(x,sizeof(x),0); 81 fillchar(y,sizeof(y),0); 82 fillchar(sa,sizeof(sa),0); 83 fillchar(rank,sizeof(rank),0); 84 fillchar(wc,sizeof(wc),0); 85 fillchar(wd,sizeof(wd),0); 86 fillchar(height,sizeof(height),0); 87 readln(ch); n:=length(ch); 88 for i:=0 to n-1 do a[i]:=ord(ch[i+1]); 89 a[n]:=0; m:=300; 90 getsa(n+1); 91 getheight(n); 92 ans:=0; 93 for i:=1 to n do ans:=ans+n-sa[i]-height[i]; 94 writeln(ans); 95 end; 96 97 close(input); 98 close(output); 99 end.
以上是关于SPOJ694&705Distinct Substrings(后缀数组)的主要内容,如果未能解决你的问题,请参考以下文章
SPOJ705 Distinct Substrings (后缀自动机&后缀数组)
spoj694 DISUBSTR - Distinct Substrings