zoukankan      html  css  js  c++  java
  • 【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.
  • 相关阅读:
    爬虫的简单运用
    预测体育竞技比赛结果(新人练手)
    自己的第一个网页
    科学计算和可视化(numpy及matplotlib学习笔记)
    面向对象总结
    PIL库的总结及运用
    jirba库的使用和好玩的词云
    第一次结队作业
    四则运算版本升级
    自动生成小学四则运算项目练习(已更新)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6418961.html
Copyright © 2011-2022 走看看