• 【POJ1743】Musical Theme(后缀数组,二分)


    题意:求一个字符串的不重叠最长相同变化的子串

    n<=20000

    思路:这是一道论文题

    我们将原串两两之间作差,可以发现所求的相同变化的子串作出的差相同

    问题就转化成了不重叠的最长重复子串

    显然答案有二分性,二分答案,将问题转化为是否存在长度为k的相同子串

    将后缀分成连续的若干组,每组相邻的height都不小于k

    有希望满足条件的两个后缀一定在同一组

    只要判断某组中的sa最大与最小值之差是否不小于k即可

    有一组满足则k满足

      1 var a,b,wc,wd,x,y,height,sa,rank:array[0..100000]of longint;
      2     n,i,l,r,mid,last,m:longint;
      3 
      4 function cmp(a,b,l:longint):boolean;
      5 begin
      6  exit((y[a]=y[b])and(y[a+l]=y[b+l]));
      7 end;
      8 
      9 procedure swap(var x,y:longint);
     10 var t:longint;
     11 begin
     12  t:=x; x:=y; y:=t;
     13 end;
     14 
     15 procedure getsa(n:longint);
     16 var i,j,p:longint;
     17 begin
     18  for i:=0 to n-1 do
     19  begin
     20   x[i]:=a[i];
     21   inc(wc[a[i]]);
     22  end;
     23  for i:=1 to m do wc[i]:=wc[i-1]+wc[i];
     24  for i:=n-1 downto 0 do
     25  begin
     26   dec(wc[x[i]]);
     27   sa[wc[x[i]]]:=i;
     28  end;
     29  j:=1; p:=1;
     30  while p<n do
     31  begin
     32   p:=0;
     33   for i:=n-j to n-1 do
     34   begin
     35    y[p]:=i; inc(p);
     36   end;
     37   for i:=0 to n-1 do
     38    if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end;
     39   for i:=0 to n-1 do wd[i]:=x[y[i]];
     40   for i:=0 to m do wc[i]:=0;
     41   for i:=0 to n-1 do inc(wc[wd[i]]);
     42   for i:=1 to m do wc[i]:=wc[i-1]+wc[i];
     43   for i:=n-1 downto 0 do
     44   begin
     45    dec(wc[wd[i]]);
     46    sa[wc[wd[i]]]:=y[i];
     47   end;
     48   for i:=0 to n do swap(x[i],y[i]);
     49   p:=1; x[sa[0]]:=0;
     50   for i:=1 to n-1 do
     51   begin
     52    if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1
     53     else begin x[sa[i]]:=p; inc(p); end;
     54   end;
     55   j:=j*2;
     56   m:=p;
     57  end;
     58 end;
     59 
     60 procedure getheight(n:longint);
     61 var i,j,k:longint;
     62 begin
     63  k:=0;
     64  for i:=1 to n do rank[sa[i]]:=i;
     65  for i:=0 to n-1 do
     66  begin
     67   if k>0 then dec(k);
     68   j:=sa[rank[i]-1];
     69   while a[i+k]=a[j+k] do inc(k);
     70   height[rank[i]]:=k;
     71  end;
     72 end;
     73 
     74 function min(x,y:longint):longint;
     75 begin
     76  if x<y then exit(x);
     77  exit(y);
     78 end;
     79 
     80 function max(x,y:longint):longint;
     81 begin
     82  if x>y then exit(x);
     83  exit(y);
     84 end;
     85 
     86 function isok(x:longint):boolean;
     87 var l,r,i:longint;
     88 begin
     89  l:=sa[0]; r:=sa[0];
     90  for i:=1 to n-1 do
     91   if height[i]<x then
     92   begin
     93    l:=sa[i]; r:=sa[i];
     94   end
     95    else
     96    begin
     97     l:=min(l,sa[i]);
     98     r:=max(r,sa[i]);
     99     if r-l>=x then exit(true);
    100    end;
    101  exit(false);
    102 end;
    103 
    104 begin
    105  assign(input,'poj1743.in'); reset(input);
    106  assign(output,'poj1743.out'); rewrite(output);
    107  while not eof do
    108  begin
    109   fillchar(a,sizeof(a),0);
    110   fillchar(b,sizeof(b),0);
    111   fillchar(sa,sizeof(sa),0);
    112   fillchar(rank,sizeof(rank),0);
    113   fillchar(x,sizeof(x),0);
    114   fillchar(y,sizeof(y),0);
    115   fillchar(height,sizeof(height),0);
    116   fillchar(wc,sizeof(wc),0);
    117   fillchar(wd,sizeof(wd),0);
    118   readln(n);
    119   if n=0 then break;
    120   for i:=0 to n-1 do read(b[i]);
    121   dec(n);
    122   for i:=0 to n-1 do a[i]:=b[i+1]-b[i]+100;
    123   a[n]:=0; m:=300;
    124   getsa(n+1);
    125   getheight(n);
    126   l:=4; r:=(n-1) div 2; last:=0;
    127   while l<=r do
    128   begin
    129    mid:=(l+r)>>1;
    130    if isok(mid) then begin last:=mid; l:=mid+1; end
    131     else r:=mid-1;
    132   end;
    133   if last<4 then writeln(0)
    134    else writeln(last+1);
    135  // for i:=1 to n do write(sa[i]+1,' ');
    136  // writeln;
    137  // for i:=0 to n do writeln(height[i]);
    138 
    139  end;
    140 
    141  close(input);
    142  close(output);
    143 end.
  • 相关阅读:
    一个想法开发与业务,我们互相依赖
    vs2005中文包,和sqlserver2005中文开发版
    C中的指针
    建立一个新的web Site
    Visual Studio 2005 中的新增安全性功能
    htm和html的区别
    完美实现导航滑动功能
    如何避免AJAX的缓存问题
    两个常用的稳定的远端CDN jquery
    推荐一个CSS排错的网址
  • 原文地址:https://www.cnblogs.com/myx12345/p/6409847.html
Copyright © 2020-2023  润新知