这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了...

解法参考论文以及下面的链接

http://www.cnblogs.com/vongang/archive/2012/11/20/2778481.html

http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6

  1 const maxn=200419;
  2 var
  3  c,h,rank,sa,x,y,stack:array[0..maxn] of longint;
  4  n,k,top:longint;
  5  a,b,d:int64;
  6  s1,s2:ansistring;
  7
  8 function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end;
  9 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end;
 10
 11 procedure make;
 12 var p,i,tot:longint;
 13 begin
 14  p:=1;
 15  while p<n do
 16   begin
 17    fillchar(c,sizeof(c),0);
 18    for i:= 1 to n-p do y[i]:=rank[i+p];
 19    for i:= n-p+1 to n do y[i]:=0;
 20    for i:= 1 to n do inc(c[y[i]]);
 21    for i:= 1 to n do inc(c[i],c[i-1]);
 22    for i:= 1 to n do
 23     begin
 24      sa[c[y[i]]]:=i;
 25      dec(c[y[i]]);
 26     end;
 27    fillchar(c,sizeof(c),0);
 28    for i:= 1 to n do x[i]:=rank[i];
 29    for i:= 1 to n do inc(c[x[i]]);
 30    for i:= 1 to n do inc(c[i],c[i-1]);
 31    for i:= n downto 1 do
 32     begin
 33      y[sa[i]]:=c[x[sa[i]]];
 34      dec(c[x[sa[i]]]);
 35     end;
 36    for i:= 1 to n do sa[y[i]]:=i;
 37    tot:=1;
 38    rank[sa[1]]:=1;
 39    for i:= 2 to n do
 40     begin
 41      if (x[sa[i]]<>x[sa[i-1]]) or (x[sa[i]+p]<>x[sa[i-1]+p]) then inc(tot);
 42      rank[sa[i]]:=tot;
 43     end;
 44    p:=p<<1;
 45   end;
 46  for i:= 1 to n do sa[rank[i]]:=i;
 47 end;
 48
 49 procedure makeh(s:ansistring);
 50 var i,j,p:longint;
 51 begin
 52  h[1]:=0; p:=0;
 53  for i:= 1 to n do
 54   begin
 55    p:=max(p-1,0);
 56    if rank[i]=1 then continue;
 57    j:=sa[rank[i]-1];
 58    while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
 59    h[rank[i]]:=p;
 60   end;
 61 end;
 62
 63 procedure init(s:ansistring);
 64 var i,tot:longint;
 65  ch:char;
 66 begin
 67  n:=length(s);
 68  for i:= 1 to n do c[i]:=0;
 69  for i:= 1 to n do x[i]:=ord(s[i]);
 70  for i:= 1 to n do inc(c[x[i]]);
 71  for i:= 1 to 122 do inc(c[i],c[i-1]);
 72  for i:= 1 to n do
 73   begin
 74    sa[c[x[i]]]:=i;
 75    dec(c[x[i]]);
 76   end;
 77  rank[sa[1]]:=1;
 78  tot:=1;
 79  for i:= 2 to n do
 80   begin
 81    if x[sa[i]]<>x[sa[i-1]] then inc(tot);
 82    rank[sa[i]]:=tot;
 83   end;
 84  fillchar(x,sizeof(x),0);
 85  fillchar(y,sizeof(y),0);
 86  make;
 87  makeh(s);
 88 end;
 89
 90 function calc(s:ansistring):int64;
 91 var ctb,i,m,ht,top:longint;
 92  ans:int64;
 93 begin
 94  ans:=0;
 95  init(s);
 96  h[0]:=k-1; h[n+1]:=k-1;
 97  top:=0; i:=1;
 98  stack[0]:=0;
 99  while i<=n+1 do
100   begin
101    ht:=h[stack[top]];
102    if ((h[i]<k) and (top=0)) or (h[i]=ht) then inc(i)
103     else if h[i]>ht then begin inc(top);stack[top]:=i; inc(i); end
104      else
105       begin
106        m:=i-stack[top]+1;
107        if (h[i]>=k) and (h[i]>h[stack[top-1]]) then
108         begin
109          ctb:=ht-h[i];
110          h[stack[top]]:=h[i];
111         end
112        else
113         begin
114          ctb:=ht-h[stack[top-1]];
115          dec(top);
116         end;
117        inc(ans,(int64(m)*int64(m-1) div 2) *int64(ctb));
118       end
119   end;
120  exit(ans);
121 end;
122
123 Begin
124  readln(k);
125  while k<>0 do
126   begin
127    readln(s1);
128    a:=calc(s1);
129    readln(s2);
130    b:=calc(s2);
131    s1:=s1+'$'+s2;
132    d:=calc(s1);
133    writeln(d-a-b);
134    readln(k);
135   end;
136 End.

转载于:https://www.cnblogs.com/EC-Ecstasy/p/4174671.html

【POJ3415】 Common Substrings (SA+单调栈)相关推荐

  1. POJ - 3415 Common Substrings(后缀数组+单调栈)

    题目链接:点击查看 题目大意:给出两个字符串,再给出一个k,问两个字符串中长度大于等于k的公共子串有多少个(种类可重复) 题目分析:因为涉及到了子串问题,先用后缀数组跑出height数组来,接下来如果 ...

  2. 2019ICPC(银川) - Largest Common Submatrix(单调栈)

    题目链接:点击查看 题目大意:给出两个n*m的矩阵,问最大的公共子矩阵的面积是多少 题目分析:一开始看到这个题目是想到了一个n^4的算法..就是暴力枚举,肯定是不行的了,最后的时候还是队友把思路一步步 ...

  3. POJ - 3415 Common Substrings(长度不小于K的公共子串个数)

    Common Substrings 后缀数组+单调栈 题解1 题解2 题解3 #include<cstdio> #include<cstring> #include<io ...

  4. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]

    题目地址 - GO-> 题目大意: 给定一个长度为 nn 的字符串SS,令TiTi表示它从第ii个字符开始的后缀,求以下这个式子的值: ∑1≤i<j≤nlen(Ti)+len(Tj)−2× ...

  5. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  6. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  7. POJ 3415 Common Substrings

    Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given t ...

  8. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  9. 【bzoj3879】SvT 后缀数组+倍增RMQ+单调栈

    题目描述 (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始位置来表示), ...

最新文章

  1. Apache httpd服务
  2. MySQL杂记(更新时间——2014.05.23)
  3. 《 Python树莓派编程》——第1章 树莓派简介 第1.1 树莓派的历史
  4. CodeForces - 1438E Yurii Can Do Everything(暴力)
  5. BZOJ 1878 HH的项链 | 主席树
  6. 【VB.NET】VB.NET基本语法常见问题的解答
  7. python写传奇脚本,Python趣味打怪:60秒学会一个例子,147段简单代码助你从入门到大师 | 中文资源...
  8. (40)FPGA面试题Verilog实现可预置初值的循环计数器
  9. 加码 2000 亿新基建还不够,阿里云再放话:今年招 5000 人!
  10. Struts1.x系列教程(16):使用LocaleAction类实现国际化的Web程序
  11. git安装 tor_【git安装教程 windows】怎么装git window_git安装配置教程
  12. 【车牌识别】基于matlab GUI BP神经网络车牌识别【含Matlab源码 669期】
  13. python实现bt下载器_10行 Python代码使用磁力链接批量下载种子
  14. 基于Tofino2的64X100GE高性能可编程交换机MX7636-64X
  15. 短视频的海绵宝宝配音怎么制作?这可能是最容易上手的配音教程
  16. 微信小程序开发入门(二)image标签及图片样式
  17. 企业网站seo优化有什么禁忌?
  18. rmarkdown入门
  19. 计算流体力学1-流体力学的控制方程
  20. TAPAS: Weakly Supervised Table Parsing via Pre-training 原论文解读

热门文章

  1. C#数组和集合专题2(Array)
  2. 转载:面向站长和网站管理员的Web缓存加速指南
  3. tensorflow分类的loss函数_Tensorflow Keras的loss函数总结
  4. python 多线程读写文件_python多线程写入文件问题
  5. _CentOS「linux」学习笔记11:crontab定时任务常用参数和基本语法
  6. mysql生成uui mybatis,MyBatis自动生成UUID并返回
  7. c#定时备份mysql数据库_C# 定时备份数据库工具源码下载
  8. element提交图片限制一张_element-ui上传图片限制图片比例
  9. python方法_详细解读Python中的__init__()方法
  10. php验证码显示碎图片,我的验证码只显示破碎的小图片