POJ3294Life Forms(后缀数组,二分)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3294Life Forms(后缀数组,二分)相关的知识,希望对你有一定的参考价值。
题意:
n<=100 len[i]<=1000
思路:这是一道论文题
1 var a,x,y,sa,rank,height,wc,wd,ans,flag,b:array[0..200000]of longint; 2 ch:array[1..200]of ansistring; 3 n,n1,l,r,mid,last,i,j,m,len:longint; 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[x[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 for i:=1 to n do rank[sa[i]]:=i; 63 k:=0; 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 function isok(x:longint):boolean; 74 var i,j,cnt,s:longint; 75 begin 76 for i:=1 to n1 do flag[i]:=1; 77 cnt:=0; s:=0; 78 for i:=1 to n do 79 if height[i]>=x then 80 begin 81 cnt:=cnt+flag[b[sa[i]]]; flag[b[sa[i]]]:=0; 82 cnt:=cnt+flag[b[sa[i-1]]]; flag[b[sa[i-1]]]:=0; 83 end 84 else 85 begin 86 if cnt>n1 div 2 then begin inc(s); ans[s]:=sa[i-1]; end; 87 cnt:=0; 88 for j:=1 to n1 do flag[j]:=1; 89 end; 90 if cnt>n1 div 2 then begin inc(s); ans[s]:=sa[n]; end; 91 if s>0 then 92 begin 93 ans[0]:=s; 94 exit(true); 95 end; 96 exit(false); 97 end; 98 99 procedure init; 100 var i:longint; 101 begin 102 {for i:=0 to n+1 do 103 begin 104 a[i]:=0; x[i]:=0; y[i]:=0; 105 sa[i]:=0; rank[i]:=0; ans[i]:=0; 106 wc[i]:=0; wd[i]:=0; b[i]:=0; 107 height[i]:=0; 108 end; } 109 fillchar(a,sizeof(a),0); 110 fillchar(b,sizeof(b),0); 111 fillchar(x,sizeof(x),0); 112 fillchar(y,sizeof(y),0); 113 fillchar(sa,sizeof(sa),0); 114 fillchar(rank,sizeof(rank),0); 115 fillchar(ans,sizeof(ans),0); 116 fillchar(wc,sizeof(wc),0); 117 fillchar(wd,sizeof(wd),0); 118 fillchar(height,sizeof(height),0); 119 end; 120 121 begin 122 assign(input,\'poj3294.in\'); reset(input); 123 assign(output,\'poj3294.out\'); rewrite(output); 124 while not eof do 125 begin 126 init; 127 readln(n1); 128 if n1=0 then break; 129 n:=0; 130 for i:=1 to n1 do 131 begin 132 readln(ch[i]); 133 len:=length(ch[i]); 134 for j:=n to n+len-1 do 135 begin 136 a[j]:=ord(ch[i][j-n+1])+100; 137 b[j]:=i; 138 end; 139 n:=n+len; a[n]:=i; 140 inc(n); 141 end; 142 dec(n); a[n]:=0; m:=300; 143 getsa(n+1); 144 getheight(n); 145 146 l:=1; r:=n; last:=0; 147 while l<=r do 148 begin 149 mid:=(l+r)>>1; 150 if isok(mid) then begin last:=mid; l:=mid+1; end 151 else r:=mid-1; 152 end; 153 if last=0 then writeln(\'?\') 154 else 155 begin 156 for i:=1 to ans[0] do 157 begin 158 for j:=ans[i] to ans[i]+last-1 do write(chr(a[j]-100)); 159 writeln; 160 end; 161 end; 162 writeln; 163 end; 164 close(input); 165 close(output); 166 end.
以上是关于POJ3294Life Forms(后缀数组,二分)的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]