首页 > 代码库 > 【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.
【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 (二分+SA)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。