很久以前写的,忘补结题报告了
两串相连中间用特殊的分隔符
然后求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[..] of longint;
  6. n,m,i,j,loc,p,k,t,f:longint;
  7. q:array[..] of node;
  8. w,ans:int64;
  9.  
  10. begin
  11. readln(k);
  12. while k<> do
  13. begin
  14. readln(s);
  15. loc:=length(s)+;
  16. readln(ss);
  17. s:=s+' '+ss;
  18. n:=length(s);
  19. fillchar(sum,sizeof(sum),);
  20. for i:= to n do
  21. begin
  22. y[i]:=ord(s[i]);
  23. inc(sum[y[i]]);
  24. end;
  25. m:=;
  26. for i:= to m do
  27. inc(sum[i],sum[i-]);
  28. for i:=n downto do
  29. begin
  30. sa[sum[y[i]]]:=i;
  31. dec(sum[y[i]]);
  32. end;
  33. p:=;
  34. rank[sa[]]:=;
  35. for i:= to n do
  36. begin
  37. if y[sa[i]]<>y[sa[i-]] then inc(p);
  38. rank[sa[i]]:=p;
  39. end;
  40. m:=p;
  41. j:=;
  42. while m<n do
  43. begin
  44. y:=rank;
  45. fillchar(sum,sizeof(sum),);
  46. p:=;
  47. for i:=n-j+ to n do
  48. begin
  49. inc(p);
  50. x[p]:=i;
  51. end;
  52. for i:= 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:= to n do
  59. begin
  60. rank[i]:=y[x[i]];
  61. inc(sum[rank[i]]);
  62. end;
  63. for i:= to m do
  64. inc(sum[i],sum[i-]);
  65. for i:=n downto do
  66. begin
  67. sa[sum[rank[i]]]:=x[i];
  68. dec(sum[rank[i]]);
  69. end;
  70. p:=;
  71. rank[sa[]]:=;
  72. for i:= to n do
  73. begin
  74. if (y[sa[i]]<>y[sa[i-]]) or (y[sa[i]+j]<>y[sa[i-]+j]) then inc(p);
  75. rank[sa[i]]:=p;
  76. end;
  77. j:=j shl ;
  78. m:=p;
  79. end;
  80. h[]:=;
  81. p:=;
  82. for i:= to n do
  83. begin
  84. if rank[i]= then continue;
  85. j:=sa[rank[i]-];
  86. while s[i+p]=s[j+p] do inc(p);
  87. h[rank[i]]:=p;
  88. if p> then dec(p);
  89. end;
  90.  
  91. ans:=;
  92. t:=;
  93. f:=;
  94. w:=;
  95. if sa[]<loc then
  96. begin
  97. w:=w+h[]-k+;
  98. q[t].h:=h[];
  99. q[t].s:=;
  100. inc(t);
  101. end;
  102. for i:= to n do
  103. begin
  104. if h[i]>=k then
  105. begin
  106. if sa[i]<loc then
  107. begin
  108. p:=;
  109. w:=w+h[i+]-k+; //w维护组内到下一个在B中的后缀(LCP-k+)和
  110. end
  111. else if sa[i]>loc then
  112. begin
  113. ans:=ans+w;
  114. if i=n then continue;
  115. p:=; //这里注意,这是B串的后缀,不能和下一个B串后缀形成公共子串
  116. end;
  117. while (f<t) and (q[t-].h>=h[i+]) do //队中height比当前大直接退,因为它的height一定不是LCP
  118. begin
  119. w:=w-(q[t-].h-h[i+])*q[t-].s; //s域维护是队列中当前元素到队中前一个元素之间有多少比它height大
  120. //这里显然之前height比当前大的元素和下一个B串后缀可能的LCP都应当是当前h[i+]
  121. p:=p+q[t-].s;
  122. dec(t);
  123. end;
  124. if p> then
  125. begin
  126. q[t].h:=h[i+];
  127. q[t].s:=p;
  128. inc(t);
  129. end;
  130. end
  131. else begin
  132. t:=;
  133. w:=;
  134. f:=;
  135. if sa[i]<loc then
  136. begin
  137. q[t].h:=h[i+];
  138. q[t].s:=;
  139. w:=h[i+]-k+;
  140. inc(t);
  141. end;
  142. end;
  143. end;
  144.  
  145. t:=;
  146. f:=;
  147. w:=;
  148. if sa[]<loc then
  149. begin
  150. w:=w+h[]-k+;
  151. q[t].h:=h[];
  152. q[t].s:=;
  153. inc(t);
  154. end;
  155. for i:= to n do
  156. begin
  157. if h[i]>=k then
  158. begin
  159. if sa[i]>loc then
  160. begin
  161. p:=;
  162. w:=w+h[i+]-k+;
  163. end
  164. else if sa[i]<loc then
  165. begin
  166. ans:=ans+w;
  167. if i=n then continue;
  168. p:=;
  169. end;
  170. while (f<t) and (q[t-].h>=h[i+]) do
  171. begin
  172. w:=w-(q[t-].h-h[i+])*q[t-].s;
  173. p:=p+q[t-].s;
  174. dec(t);
  175. end;
  176. if p> then
  177. begin
  178. q[t].h:=h[i+];
  179. q[t].s:=p;
  180. inc(t);
  181. end;
  182. end
  183. else begin
  184. t:=;
  185. w:=;
  186. f:=;
  187. if sa[i]>loc then
  188. begin
  189. q[t].h:=h[i+];
  190. q[t].s:=;
  191. w:=h[i+]-k+;
  192. inc(t);
  193. end;
  194. end;
  195. end;
  196. writeln(ans);
  197. readln(k);
  198. end;
  199. end.

poj3415的更多相关文章

  1. 【POJ3415】 Common Substrings(后缀数组|SAM)

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

  2. poj3415(后缀数组)

    poj3415 题意 给定两个字符串,给出长度 \(m\) ,问这两个字符串有多少对长度大于等于 \(m\) 且完全相同的子串. 分析 首先连接两个字符串 A B,中间用一个特殊符号分割开. 按照 \ ...

  3. POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数

    题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K ...

  4. 【POJ3415】Common Substrings(后缀数组,单调栈)

    题意: n<=1e5 思路: 我的做法和题解有些不同 题解是维护A的单调栈算B的贡献,反过来再做一次 我是去掉起始位置不同这个限制条件先算总方案数,再把两个串内部不合法的方案数减去 式子展开之后 ...

  5. POJ3415 Common Substrings(后缀数组 单调栈)

    借用罗穗骞论文中的讲解: 计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按height ...

  6. poj3415 Common Substrings(后缀数组,单调栈 | 后缀自动机)

    [题目链接] http://poj.org/problem?id=3415 [题意] A与B长度至少为k的公共子串个数. [思路] 基本思想是将AB各个后缀的lcp-k+1的值求和.首先将两个字符串拼 ...

  7. POJ3415 Common Substrings

    后缀数组 求长度不小于k的公共子串的个数 代码: #include <stdio.h> #include <string.h> ; int len, len1; int wa[ ...

  8. 2018.12.15 poj3415 Common Substrings(后缀自动机)

    传送门 后缀自动机基础题. 给两个字符串,让你求长度不小于kkk的公共子串的数量. 这题可以用后缀自动机解决废话 考虑对其中一个字串建出后缀自动机,然后用另一个在上面跑,注意到如果一个状态有贡献的话, ...

  9. 【poj3415】 Common Substrings

    http://poj.org/problem?id=3415 (题目链接) 题意 给定两个字符串 A 和 B,求长度不小于 k 的公共子串的个数(可以相同). Solution 后缀数组论文题... ...

随机推荐

  1. 轻松应对C10k问题

    http://blog.csdn.net/u011011917/article/details/17203539 传统的.教科书里的I/O复用等待函数select/poll在处理数以万计的客户端连接时 ...

  2. Java Web应用启动间隔执行的程序

    Reference:<Java定时器timer.schedule在Web中间隔执行任务和定时><[Java]Timer和TimerTask详解> 做了一个Demo,完成如下的功 ...

  3. IOS分类(Category)

    分类(Category):拓展原有类的方法,而不影响原有类的子类,分类中不能创建成员变量. 分类的使用: 1.创建分类: 如图点击(File)选择(New)->(File).. 或者使用快捷键c ...

  4. windows phone 8 设置锁屏背景

    本来想研究一下 利用闪光灯实现手电筒的代码,发现不是简答设置FlashMode属性可以解决问题的,ms也没有提供api,无意瞄了一眼侧边栏的文章列表,发现了设置屏幕锁屏背景的实现,手一抖点进去了.还算 ...

  5. C++11中新特性之:unordered_map

    unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value. 不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的ha ...

  6. 01_C语言基础

    内容提要: 1. C语言概述2. 数据类型.运算符与表达式3. C语言程序结构 4. VC6.0使用练习 知识详解01:C语言的历史 1. C语言与其它语言比较 汇编语言: (1).可直接对硬件进行操 ...

  7. 《JavaScript高级程序设计》笔记(3):传递参数

    待更新... 9.17更新: ECMAScript中所有函数的参数都是按值传递的.也就是说,把函数外部复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样.基本类型值的传递如同基本类型变量的复 ...

  8. JavaScript语言用10张图

    JavaScript 语言基础知识点总结,用图片树形结构说明.包括Windows对象.JavaScriptDOM基本操作.JavaScript变量.JavaScript数据类型.JavaScript运 ...

  9. 以查询方式实现1s定时

    以查询控制器的控制位状态来实现1s定时. #include <reg52.h> sbit LED = P0^; unsigned ; void main () { LED = ; // 点 ...

  10. ios8.1.2耗电情况严重的解决方法

    打开cydia,搜索ifile(威锋源,版本2.1.0-1).打开ifile,进入路径/Applications.里面有许多程序文件,选择适当的进行禁用(ifile可以禁用程序的活动而不完全删除它,这 ...