zoukankan      html  css  js  c++  java
  • poj3294

    首先后缀数组预处理
    然后二分答案len很显然,然后考虑怎么判定
    我们用左右指针顺着名次扫描一下,初始左右指针为1
    根据LCP(i,j)=min(height[rank[i]+1]~height[rank[j]]) 设rank[i]<rank[j]
    移动右指针扫描得到一组后缀[i,j]之间LCP>=len,h[j+1]<len
    然后判断一下这组后缀是否有超过半数的原串,如果满足则记录
    然后左右指针都从j+1开始
    由于每个后缀最多被扫描一次判断一次,所以必然O(n)
    注意多个串相连接的时候要用不同的字符作为分隔符

      1 var ans,x,y,sa,sum,rank,h,loc:array[0..200010] of longint;
      2     v:array[0..500] of boolean;
      3     j,len,l,r,k,i,n,m,p,tot:longint;
      4     s,ch:ansistring;
      5 
      6 procedure suffix;
      7   begin
      8     fillchar(sum,sizeof(sum),0);
      9     for i:=1 to n do
     10     begin
     11       y[i]:=ord(s[i]);
     12       inc(sum[y[i]]);
     13     end;
     14     m:=255;
     15     for i:=1 to m do
     16       sum[i]:=sum[i-1]+sum[i];
     17     for i:=n downto 1 do
     18     begin
     19       sa[sum[y[i]]]:=i;
     20       dec(sum[y[i]]);
     21     end;
     22     p:=1;
     23     rank[sa[1]]:=1;
     24     for i:=2 to n do
     25     begin
     26       if (y[sa[i]]<>y[sa[i-1]]) then inc(p);
     27       rank[sa[i]]:=p;
     28     end;
     29     m:=p;
     30     j:=1;
     31     while m<n do
     32     begin
     33       fillchar(sum,sizeof(sum),0);
     34       y:=rank;
     35       p:=0;
     36       for i:=n-j+1 to n do
     37       begin
     38         inc(p);
     39         x[p]:=i;
     40       end;
     41       for i:=1 to n do
     42         if sa[i]>j then
     43         begin
     44           inc(p);
     45           x[p]:=sa[i]-j;
     46         end;
     47 
     48       for i:=1 to n do
     49       begin
     50         rank[i]:=y[x[i]];
     51         inc(sum[rank[i]]);
     52       end;
     53       for i:=1 to m do
     54         inc(sum[i],sum[i-1]);
     55       for i:=n downto 1 do
     56       begin
     57         sa[sum[rank[i]]]:=x[i];
     58         dec(sum[rank[i]]);
     59       end;
     60       p:=1;
     61       rank[sa[1]]:=1;
     62       for i:=2 to n do
     63       begin
     64         if (y[sa[i]]<>y[sa[i-1]]) or (y[sa[i]+j]<>y[sa[i-1]+j]) then inc(p);
     65         rank[sa[i]]:=p;
     66       end;
     67       m:=p;
     68       j:=j shl 1;
     69     end;
     70     h[1]:=0;
     71     p:=0;
     72     for i:=1 to n do
     73     begin
     74       if rank[i]=1 then continue;
     75       j:=sa[rank[i]-1];
     76       while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
     77       h[rank[i]]:=p;
     78       if p>0 then dec(p);
     79     end;
     80   end;
     81 
     82 function solve(l,r:longint):boolean;
     83   var i,t:longint;
     84   begin
     85     fillchar(v,sizeof(v),false);
     86     t:=0;
     87     for i:=l to r do
     88       if (loc[sa[i]]<>-1) then
     89         if not v[loc[sa[i]]] then
     90         begin
     91           inc(t);
     92           v[loc[sa[i]]]:=true;
     93         end;
     94     if t>k shr 1 then exit(true) else exit(false);
     95   end;
     96 
     97 function check(len:longint):boolean;
     98   var b,e,i:longint;
     99       fl:boolean;
    100 
    101   begin
    102     fl:=false;
    103     b:=1;
    104     e:=1;
    105     for i:=2 to n do
    106     begin
    107       if h[i]>=len then inc(e)
    108       else begin
    109         if solve(b,e) then
    110         begin
    111           if not fl then tot:=0;
    112           fl:=true;
    113           inc(tot);
    114           ans[tot]:=sa[b];
    115         end;
    116         b:=i;   
    117         e:=i;
    118       end;
    119     end;
    120     if b<e then  //注意收尾
    121     begin
    122       if solve(b,e) then
    123       begin
    124         if not fl then tot:=0;
    125         inc(tot);
    126         fl:=true;
    127         ans[tot]:=sa[b];
    128       end;
    129     end;
    130     exit(fl);
    131   end;
    132 
    133 begin
    134   readln(k);
    135   while k<>0 do
    136   begin
    137     s:='';
    138     r:=0;
    139     m:=0;
    140     for i:=1 to k do
    141     begin
    142       readln(ch);
    143       if r<length(ch) then r:=length(ch);
    144       for j:=1 to length(ch) do
    145       begin
    146         inc(m);
    147         loc[m]:=i;
    148       end;
    149       inc(m);
    150       loc[m]:=-1;
    151       s:=s+ch+chr(i);
    152     end;
    153     n:=length(s);
    154     suffix;
    155     l:=1;
    156     len:=0;
    157     while l<=r do
    158     begin
    159       m:=(l+r) shr 1;
    160       if check(m) then
    161       begin
    162         len:=m;
    163         l:=m+1;
    164       end
    165       else r:=m-1;
    166     end;
    167     if k=1 then
    168     begin
    169       writeln(s);
    170       writeln;
    171     end
    172     else if len=0 then
    173     begin
    174       writeln('?');
    175       writeln;
    176     end
    177     else begin
    178       for i:=1 to tot do
    179       begin;
    180         for j:=ans[i] to ans[i]+len-1 do
    181           write(s[j]);
    182         writeln;
    183       end;
    184       writeln;
    185     end;
    186     readln(k);
    187   end;
    188 end.
    View Code
  • 相关阅读:
    JS、JQuery和ExtJs的跨域处理
    百度地图API的IP定位城市和浏览器定位(转)
    jQuery简单易用的网页内容打印插件
    JS控制打印指定div
    好久没弄数学了,一本书上出现了,应该是指代了什么意思,问下.
    Java String类型数据的字节长度
    【转】oracle回闪操作
    c3p0数据库连接池死锁问题
    easyui datagrid 单选框 效果
    js插件---webuploader 使用(lavarel中使用)
  • 原文地址:https://www.cnblogs.com/phile/p/4473147.html
Copyright © 2011-2022 走看看