题意:【POJ3294】Life Forms(后缀数组,二分)_C语言

n<=100 len[i]<=1000

思路:这是一道论文题

【POJ3294】Life Forms(后缀数组,二分)_C_02

  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.