后缀数组poj2774 poj3415

来源:互联网 发布:glibc 源码 编辑:程序博客网 时间:2024/04/28 10:05
 【问题描述】  
  给出两个字符串T和P,请你用后缀数组完成下列任务:

  任务1、计算这两个字符串的最长公共子串,并输出字典序最小的公共串。

  任务2、计算长度不小于K的公共子串的个数(子串相同但位置不同算不同的子串)。
  例如:T="xx",P="xx",K=1,则长度不小于K 的公共子串的个数是5。
  再如:T="aababaa",P="abaabaa",K=2,则长度不小于K 的公共子串的个数是22。    【输入】  
  含3行,第一行是字符串T,第二行是字符串P,第3行一个整数K。    【输出】  
  含3行:
  第1行一个整数,表示T和P的最长公共子串长度。
  第2行一个字符串,表示T和P字典序最小的公共子串。
  第3行一个字符串,表示T和P长度不小于K的公共子串数目。
  

分别对应任务1和任务2的答案。    【样例输入】  
aababaa
abaabaa
2    【样例输出】  
4
aaba
22    【数据范围】  
字符串长度不超过100 000,1<=K<=100 000

 

 

 

 

【样例解释】

 

 


  任务1、"aababaa"和"abaabaa",的最长公共子串为"aaba"或"abaa";

  任务2、"aababaa"和"abaabaa",长度不小于2的不同公共子串有:
  1、"aa" 共有4个;
  2、"ab" 共有4个;
  3、"ba" 共有4个;
  4、"aab" 共有1个;
  5、"aba" 共有4个;
  6、"baa" 共有2个;
  7、"aaba" 共有1个;
  8、"abaa" 共有2个;

  总共4+4+4+1+4+2+1+2=22个。

poj2774 poj3415

 

【问题分析】

task1:

可以等价于求两串所有后缀的最长公共前缀。

加一个奇葩的分隔符将两串连接起来,并标记新串s中的每个字符s[i](s[i]属于T则将i标记为1,s[i]属于P则将i标记为2,s[i]为分隔符则标记为0),求后缀数组,求height数组。

显然,如果求一个串的最长重复子串(可重叠),则ans=max(height[i]),但本题要求不是同一个字符串的两个后缀,所以更新答案前先判断一下sa[i]与sa[i-1]是否分属T,P即可。

 

task2:

对于P,T的两个后缀i,j,若LCP(i,j)=l,则对答案的贡献为l-k+1。

按task1连接成新串后,按height分组,每组内相邻后缀的height>=K,显然不同组之间是相互独立的,对于每一组,要求出所有P之前的T与之LCP-K+1的和,以及所有T之前的P与之的LCP-K+1的和,累加到ans中,显然暴力枚举的时间复杂度为O(N^2)。

经分析,这又是两个等价问题。现在只考虑求出所有P在同一组内之前的所有T与之LCP-K+1的和。

对于任意一个P来说,在它前面的T与之的LCP是单调不减的。从左到右扫描sa,当前元素为i,设h=height[i+1]-K+1为当前i与P0(i右边同一组元素中最近的P)的答案贡献。设一个单调递增的栈stack,stack[top].h为栈顶元素与当前P0的答案贡献,stack[top].x为答案贡献为stack[top].h的T元素有多少个。设sum=本组内当前所有扫过的T与P0的总贡献。

若当前元素i为P,ans=ans+sum;

将当前元素加入栈中,维护sum;

 

 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 pythen3.7 wheel 数据分析 二值图像 二值图像连通 ajax时间 ajax获取时间传到后台 ajax获取服务器时间传到后台 submit提交时怎么将提交的时间传入后台 gethostbyname 分节符快捷键 ErrorPage! Reason:*Networkbusy*InvalidURL*Failedto install_flash_player_10_active_x 伊织 伊织调教 起重机司机学习 ssni 输入梯形上底下底高,输出面积 python语言,输入梯形上底下底高输出面积 网易产品 https://www.csdndoc.com/blog/390696 https://www.cocoacontrols.com 风之教堂 黄色网站 AV网站 439973416 فیلترشکن WS_CLIPCHILDREN设置键在哪里 数据结构(严蔚敏李冬梅)课后答案 ipz809 一个字包含的二进制位数 linux面试 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 【题目2】设计一个结构体类型,包含姓名、出生日期。其中出生日期又包含年、月、日三部分信息。输入n个好 结构体比较好友中年纪最小的 matlab三维矩阵可视化 使QQ崩溃 scanIP 按照规定,在高速公路上行使的机动车,达到或超出本车道限速的10%则处200元罚款;若达到或超出50% c语言输入三个数字 c语言如何输入三个数求平均值