【POJ2406】Power Strings(KMP,后缀数组)
题意:
n<=1000000,cas较大
思路:这是一道论文题
后缀数组已弃疗,强行需要DC3构造,懒得(不会)写
1 var a,x,y,sa,rank,height,dp,wc,wd:array[0..1000010]of longint; 2 n,m,i,j,len,ans,st:longint; 3 ch:ansistring; 4 flag:boolean; 5 6 function min(x,y:longint):longint; 7 begin 8 if x<y then exit(x); 9 exit(y); 10 end; 11 12 function cmp(a,b,l:longint):boolean; 13 begin 14 exit((y[a]=y[b])and(y[a+l]=y[b+l])); 15 end; 16 17 procedure swap(var x,y:longint); 18 var t:longint; 19 begin 20 t:=x; x:=y; y:=t; 21 end; 22 23 procedure getsa(n:longint); 24 var i,j,p:longint; 25 begin 26 for i:=0 to m do wc[i]:=0; 27 for i:=0 to n-1 do 28 begin 29 x[i]:=a[i]; 30 inc(wc[a[i]]); 31 end; 32 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 33 for i:=n-1 downto 0 do 34 begin 35 dec(wc[x[i]]); 36 sa[wc[x[i]]]:=i; 37 end; 38 j:=1; p:=1; 39 while p<n do 40 begin 41 p:=0; 42 for i:=n-j to n-1 do 43 begin 44 y[p]:=i; inc(p); 45 end; 46 for i:=0 to n-1 do 47 if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end; 48 for i:=0 to n-1 do wd[i]:=x[y[i]]; 49 for i:=0 to m-1 do wc[i]:=0; 50 for i:=0 to n-1 do inc(wc[wd[i]]); 51 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 52 for i:=n-1 downto 0 do 53 begin 54 dec(wc[wd[i]]); 55 sa[wc[wd[i]]]:=y[i]; 56 end; 57 for i:=0 to n do swap(x[i],y[i]); 58 p:=1; x[sa[0]]:=0; 59 for i:=1 to n-1 do 60 if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1 61 else begin x[sa[i]]:=p; inc(p); end; 62 j:=j*2; 63 m:=p; 64 end; 65 end; 66 67 procedure getheight(n:longint); 68 var i,j,k:longint; 69 begin 70 for i:=1 to n do rank[sa[i]]:=i; 71 k:=0; 72 for i:=0 to n-1 do 73 begin 74 if k>0 then dec(k); 75 j:=sa[rank[i]-1]; 76 while a[i+k]=a[j+k] do inc(k); 77 height[rank[i]]:=k; 78 end; 79 end; 80 81 {procedure init; 82 begin 83 fillchar(a,sizeof(a),0); 84 fillchar(x,sizeof(x),0); 85 fillchar(y,sizeof(y),0); 86 fillchar(sa,sizeof(sa),0); 87 fillchar(rank,sizeof(rank),0); 88 fillchar(height,sizeof(height),0); 89 fillchar(dp1,sizeof(dp1),0); 90 fillchar(dp2,sizeof(dp2),0); 91 end; } 92 93 begin 94 assign(input,'data.in'); reset(input); 95 assign(output,'poj2406.out'); rewrite(output); 96 while not eof do 97 begin 98 //init; 99 readln(ch); 100 n:=length(ch); 101 if ch='.' then break; 102 for i:=0 to n do 103 begin 104 height[i]:=0; sa[i]:=0; rank[i]:=0; 105 dp[i]:=0; 106 end; 107 for i:=0 to n-1 do a[i]:=ord(ch[i+1]); 108 a[n]:=1; m:=200; 109 getsa(n+1); 110 getheight(n); 111 dp[rank[0]]:=maxlongint; 112 for i:=rank[0]+1 to n do dp[i]:=min(height[i],dp[i-1]); 113 for i:=rank[0]-1 downto 0 do dp[i]:=min(height[i+1],dp[i+1]); 114 ans:=1; 115 for i:=1 to n div 2 do 116 if n mod i=0 then 117 begin 118 st:=n-i; 119 if dp[rank[i]]=n-i then begin ans:=n div i; break; end; 120 end; 121 writeln(ans); 122 end; 123 end.
显然钦定的算法是KMP
1 var a:ansistring; 2 next:array[0..2000000]of longint; 3 n,i,j:longint; 4 5 begin 6 7 while not eof do 8 begin 9 readln(a); 10 if a='.' then break; 11 n:=length(a); 12 i:=0; j:=1; 13 next[1]:=0; 14 while j<=n do 15 begin 16 if (i=0)or(a[i]=a[j]) then 17 begin 18 inc(i); inc(j); 19 next[j]:=i; 20 end 21 else i:=next[i]; 22 end; 23 if n mod (n-next[n+1]+1)=0 then 24 writeln(n div (n-next[n+1]+1)) 25 else writeln(1); 26 for i:=0 to n+1 do next[i]:=0; 27 end; 28 29 end.
null