zoukankan      html  css  js  c++  java
  • poj3415

    很久以前写的,忘补结题报告了
    两串相连中间用特殊的分隔符
    然后求height,由于要求求公共子串大于等于k的个数,并且只要位置不同即可
    因此不难想到在名次上对height分组,一组内的height保证>=k
    下面就是在组内统计的问题了
    然后还是不难发现,分别在AB串中的后缀i,j,他们能产生2*[LCP(i,j)-k+1]个公共子串
    然后那个著名的性质LCP(i,j)=min(h[rank[i]+1]~h[rank[j]]) (令rank[i]<rank[j])
    不难想到维护一个单调增的队列,遇到在B串就统计并维护,遇到在A串就维护
    然后再反过来做一遍
    具体维护单调队列见程序,否则感觉讲不清

      1 type node=record
      2        h,s:longint;
      3      end;
      4 var s,ss:ansistring;
      5     h,sa,sum,y,x,rank:array[0..201000] of longint;
      6     n,m,i,j,loc,p,k,t,f:longint;
      7     q:array[0..2010000] of node;
      8     w,ans:int64;
      9 
     10 begin
     11   readln(k);
     12   while k<>0 do
     13   begin
     14     readln(s);
     15     loc:=length(s)+1;
     16     readln(ss);
     17     s:=s+' '+ss;
     18     n:=length(s);
     19     fillchar(sum,sizeof(sum),0);
     20     for i:=1 to n do
     21     begin
     22       y[i]:=ord(s[i]);
     23       inc(sum[y[i]]);
     24     end;
     25     m:=255;
     26     for i:=2 to m do
     27       inc(sum[i],sum[i-1]);
     28     for i:=n downto 1 do
     29     begin
     30       sa[sum[y[i]]]:=i;
     31       dec(sum[y[i]]);
     32     end;
     33     p:=1;
     34     rank[sa[1]]:=1;
     35     for i:=2 to n do
     36     begin
     37       if y[sa[i]]<>y[sa[i-1]] then inc(p);
     38       rank[sa[i]]:=p;
     39     end;
     40     m:=p;
     41     j:=1;
     42     while m<n do
     43     begin
     44       y:=rank;
     45       fillchar(sum,sizeof(sum),0);
     46       p:=0;
     47       for i:=n-j+1 to n do
     48       begin
     49         inc(p);
     50         x[p]:=i;
     51       end;
     52       for i:=1 to n do
     53         if sa[i]>j then
     54         begin
     55           inc(p);
     56           x[p]:=sa[i]-j;
     57         end;
     58       for i:=1 to n do
     59       begin
     60         rank[i]:=y[x[i]];
     61         inc(sum[rank[i]]);
     62       end;
     63       for i:=2 to m do
     64         inc(sum[i],sum[i-1]);
     65       for i:=n downto 1 do
     66       begin
     67         sa[sum[rank[i]]]:=x[i];
     68         dec(sum[rank[i]]);
     69       end;
     70       p:=1;
     71       rank[sa[1]]:=1;
     72       for i:=2 to n do
     73       begin
     74         if (y[sa[i]]<>y[sa[i-1]]) or (y[sa[i]+j]<>y[sa[i-1]+j]) then inc(p);
     75         rank[sa[i]]:=p;
     76       end;
     77       j:=j shl 1;
     78       m:=p;
     79     end;
     80     h[1]:=0;
     81     p:=0;
     82     for i:=1 to n do
     83     begin
     84       if rank[i]=1 then continue;
     85       j:=sa[rank[i]-1];
     86       while s[i+p]=s[j+p] do inc(p);
     87       h[rank[i]]:=p;
     88       if p>0 then dec(p);
     89     end;
     90 
     91     ans:=0;
     92     t:=0;
     93     f:=0;
     94     w:=0;
     95     if sa[1]<loc then
     96     begin
     97       w:=w+h[2]-k+1;
     98       q[t].h:=h[2];
     99       q[t].s:=1;
    100       inc(t);
    101     end;
    102     for i:=2 to n do
    103     begin
    104       if h[i]>=k then
    105       begin
    106         if sa[i]<loc then
    107         begin
    108           p:=1;
    109           w:=w+h[i+1]-k+1; //w维护组内到下一个在B中的后缀(LCP-k+1)和
    110         end
    111         else if sa[i]>loc then
    112         begin
    113           ans:=ans+w;
    114           if i=n then continue;
    115           p:=0;  //这里注意,这是B串的后缀,不能和下一个B串后缀形成公共子串
    116         end;
    117         while (f<t) and (q[t-1].h>=h[i+1]) do //队中height比当前大直接退,因为它的height一定不是LCP
    118         begin
    119           w:=w-(q[t-1].h-h[i+1])*q[t-1].s;  //s域维护是队列中当前元素到队中前一个元素之间有多少比它height大
    120                                  //这里显然之前height比当前大的元素和下一个B串后缀可能的LCP都应当是当前h[i+1]
    121           p:=p+q[t-1].s;
    122           dec(t);
    123         end;
    124         if p>0 then
    125         begin
    126           q[t].h:=h[i+1];
    127           q[t].s:=p;
    128           inc(t);
    129         end;
    130       end
    131       else begin
    132         t:=0;
    133         w:=0;
    134         f:=0;
    135         if sa[i]<loc then
    136         begin
    137           q[t].h:=h[i+1];
    138           q[t].s:=1;
    139           w:=h[i+1]-k+1;
    140           inc(t);
    141         end;
    142       end;
    143     end;
    144 
    145     t:=0;
    146     f:=0;
    147     w:=0;
    148     if sa[1]<loc then
    149     begin
    150       w:=w+h[2]-k+1;
    151       q[t].h:=h[2];
    152       q[t].s:=1;
    153       inc(t);
    154     end;
    155     for i:=2 to n do
    156     begin
    157       if h[i]>=k then
    158       begin
    159         if sa[i]>loc then
    160         begin
    161           p:=1;
    162           w:=w+h[i+1]-k+1;
    163         end
    164         else if sa[i]<loc then
    165         begin
    166           ans:=ans+w;
    167           if i=n then continue;
    168           p:=0;
    169         end;
    170         while (f<t) and (q[t-1].h>=h[i+1]) do
    171         begin
    172           w:=w-(q[t-1].h-h[i+1])*q[t-1].s;
    173           p:=p+q[t-1].s;
    174           dec(t);
    175         end;
    176         if p>0 then
    177         begin
    178           q[t].h:=h[i+1];
    179           q[t].s:=p;
    180           inc(t);
    181         end;
    182       end
    183       else begin
    184         t:=0;
    185         w:=0;
    186         f:=0;
    187         if sa[i]>loc then
    188         begin
    189           q[t].h:=h[i+1];
    190           q[t].s:=1;
    191           w:=h[i+1]-k+1;
    192           inc(t);
    193         end;
    194       end;
    195     end;
    196     writeln(ans);
    197     readln(k);
    198   end;
    199 end.
    View Code
  • 相关阅读:
    JVM体系结构之五:本地方法栈
    netty中的ByteBuf
    AtomicLong和LongAdder的区别
    Python介绍
    netty支持的协议
    spring扩展点之四:Spring Aware容器感知技术,BeanNameAware和BeanFactoryAware接口,springboot中的EnvironmentAware
    Netty组件
    《深入Java虚拟机学习笔记》- 第9章 垃圾收集
    《深入Java虚拟机学习笔记》- 第8章 连接模型
    netty中的EventLoop和EventLoopGroup
  • 原文地址:https://www.cnblogs.com/phile/p/4473010.html
Copyright © 2011-2022 走看看