首页 > 代码库 > 【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 (二分+SA)

【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 (二分+SA)

求重复k次的最长重复子串,解法见罗穗骞大神的后缀数组论文

  1 const maxn=100419;  2    3 var  4  x,y,rank,sa,h,s,num,c:array[0..maxn] of longint;  5  n,time:longint;  6    7 function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end;  8 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end;  9 procedure make; 10 var i,j,p,tot:longint; 11 begin 12  p:=1; 13  while p<n do 14   begin 15    fillchar(c,sizeof(c),0); 16    for i:= 1 to n-p do y[i]:=rank[i+p]; 17    for i:= n-p+1 to n do y[i]:=0; 18    for i:= 1 to n do inc(c[y[i]]); 19    for i:= 1 to n do inc(c[i],c[i-1]); 20    for i:= 1 to n do 21     begin 22      sa[c[y[i]]]:=i; 23      dec(c[y[i]]); 24     end; 25    fillchar(c,sizeof(c),0); 26    for i:= 1 to n do x[i]:=rank[i]; 27    for i:= 1 to n do inc(c[x[i]]); 28    for i:= 1 to n do inc(c[i],c[i-1]); 29    for i:= n downto 1 do 30     begin 31      y[sa[i]]:=c[x[sa[i]]]; 32      dec(c[x[sa[i]]]); 33     end; 34    for i:= 1 to n do sa[y[i]]:=i; 35    tot:=1; 36    rank[sa[1]]:=1; 37    for i:= 2 to n do 38     begin 39      if (x[sa[i]]<>x[sa[i-1]]) or (x[sa[i]+p]<>x[sa[i-1]+p]) then inc(tot); 40      rank[sa[i]]:=tot; 41     end; 42    p:=p<<1; 43   end; 44 end; 45   46 procedure makeht; 47 var i,j,p:longint; 48 begin 49  h[1]:=0; p:=0; 50  for i:= 1 to n do 51   begin 52    p:=max(p-1,0); 53    if rank[i]=1 then continue; 54    j:=sa[rank[i]-1]; 55    while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p); 56    h[rank[i]]:=p; 57   end; 58 end; 59   60 procedure init; 61 var i,j,tot:longint; 62  ch:char; 63 begin 64  readln(n,time); 65  for i:= 1 to n do readln(s[i]); 66  for i:= 1 to n do x[i]:=s[i]; 67  fillchar(c,sizeof(c),0); 68  for i:= 1 to n do inc(c[x[i]]); 69  for i:= 1 to 180 do inc(c[i],c[i-1]); 70  for i:= 1 to n do 71   begin 72    sa[c[x[i]]]:=i; 73    dec(c[x[i]]); 74   end; 75  rank[sa[1]]:=1; 76  tot:=1; 77  for i:= 2 to n do 78   begin 79    if x[sa[i]]<>x[sa[i-1]] then inc(tot); 80    rank[sa[i]]:=tot; 81   end; 82  make; 83  makeht; 84 end; 85   86 function check(k:longint):boolean; 87 var i,j,x,y:longint; 88 begin 89  i:=1; 90  while i<=n do 91   begin 92    j:=i; 93    while (j<n) and (h[j+1]>=k) do inc(j); 94    if j-i+1>=time then exit(true); 95    i:=j+1; 96   end; 97  exit(false); 98 end; 99  100 procedure solve;101 var l,r,mid,ans:longint;102 begin103  l:=0; r:=n>>1; ans:=0;104  while l<=r do105   begin106    mid:=(l+r)>>1;107    if check(mid) then108     begin109      l:=mid+1;110      ans:=mid;111     end112    else r:=mid-1;113   end;114  writeln(ans);115 end;116  117 Begin118  init;119  solve;120 End.
View Code

 

【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 (二分+SA)