【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.

 

posted on 2017-02-20 12:25  myx12345  阅读(184)  评论(0编辑  收藏  举报

导航