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 two strings A, B and one integer K, we define S, a set of triples (i, j, k):
S = {(i, j, k) | k≥K, A(i, k)=B(j, k)}.
You are to give the value of |S| for specific A, B and K.
Input
The input file contains several blocks of data. For each block, the first line contains one integer K, followed by two lines containing strings A and B, respectively. The input file is ended by K=0.
1 ≤ |A|, |B| ≤ 105
1 ≤ K ≤ min{|A|, |B|}
Characters of A and B are all Latin letters.
Output
For each case, output an integer |S|.
Sample Input
2 aababaa abaabaa 1 xx xx 0
Sample Output
22
5
题目大意:给定两串A,B,找出A,B的长度大于k的公共子串的个数 题解:显然后缀数组,将两个串合并 然后显然中间加一个‘#’阻断height越界然后会发现求出high之后两串若分属A,B两串 显然 对答案贡献为lcp-k+1再根据老套路 利用 height 递增的性质去维护单调栈,记录栈中lcp-k+1的值的总和 tot如果当前height[i]大于栈顶就统计 如果height[i]<=栈顶 我们直接将栈顶和height[i]合并调了很久最后发现把l开成了char = =|
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 using namespace std; 8 typedef long long ll; 9 const int N=400005; 10 int s[N];char S1[N],S2[N];int n,l,tmp[N],rk[N],sa[N],high[N],K,k; 11 bool comp(int i,int j){ 12 if(rk[i]!=rk[j])return rk[i]<rk[j]; 13 int ri=i+k<=n?rk[i+k]:-1; 14 int rj=j+k<=n?rk[j+k]:-1; 15 return ri<rj; 16 } 17 void Getsa(){ 18 for(int i=1;i<=n;i++){ 19 sa[i]=i;rk[i]=s[i]; 20 } 21 for(k=1;k<=n;k<<=1){ 22 sort(sa+1,sa+n+1,comp); 23 for(int i=1;i<=n;i++)tmp[sa[i]]=tmp[sa[i-1]]+comp(sa[i-1],sa[i]); 24 for(int i=1;i<=n;i++)rk[i]=tmp[i]; 25 } 26 } 27 void Gethight(){ 28 int h=0,j; 29 for(int i=1;i<=n;i++){ 30 j=sa[rk[i]-1]; 31 if(h)h--; 32 for(;i+h<=n && j+h<=n;h++)if(s[i+h]!=s[j+h])break; 33 high[rk[i]-1]=h; 34 } 35 } 36 ll ans=0; 37 struct stacker{ 38 int lcp,cnt; 39 }st[N<<1]; 40 void Getanswer() 41 { 42 ll tot=0,cnt=0;int top=0; 43 for(int i=1;i<n;i++){ 44 if(high[i]<K){ 45 top=tot=0; 46 continue; 47 } 48 cnt=0; 49 if(sa[i]<l)cnt++,tot+=high[i]-K+1; 50 while(top && high[i]<=st[top].lcp){ 51 tot-=(ll)(st[top].lcp-high[i])*st[top].cnt; 52 cnt+=st[top].cnt; 53 top--; 54 } 55 st[++top].lcp=high[i];st[top].cnt=cnt; 56 if(sa[i+1]>l)ans+=tot; 57 } 58 tot=0;top=0;cnt=0; 59 for(int i=1;i<n;i++){ 60 if(high[i]<K){ 61 top=tot=0; 62 continue; 63 } 64 cnt=0; 65 if(sa[i]>l)cnt++,tot+=high[i]-K+1; 66 while(top && high[i]<=st[top].lcp){ 67 tot-=(ll)(st[top].lcp-high[i])*st[top].cnt; 68 cnt+=st[top].cnt; 69 top--; 70 } 71 st[++top].lcp=high[i];st[top].cnt=cnt; 72 if(sa[i+1]<l)ans+=tot; 73 } 74 } 75 void work(){ 76 n=0;ans=0; 77 scanf("%s%s",S1,S2); 78 l=strlen(S1); 79 for(int i=0;i<l;i++)s[++n]=S1[i]; 80 s[++n]='#';l++; 81 for(int i=0,sz=strlen(S2);i<sz;i++)s[++n]=S2[i]; 82 s[n+1]=0; 83 Getsa(); 84 Gethight(); 85 Getanswer(); 86 printf("%lld\n",ans); 87 } 88 int main() 89 { 90 freopen("pp.in","r",stdin); 91 freopen("pp.out","w",stdout); 92 while(scanf("%d",&K)) 93 { 94 if(!K)break; 95 work(); 96 } 97 return 0; 98 }
View Code
转载于:https://www.cnblogs.com/Yuzao/p/7163054.html
POJ 3415 Common Substrings相关推荐
- POJ - 3415 Common Substrings(长度不小于K的公共子串个数)
Common Substrings 后缀数组+单调栈 题解1 题解2 题解3 #include<cstdio> #include<cstring> #include<io ...
- POJ - 3415 Common Substrings(后缀数组+单调栈)
题目链接:点击查看 题目大意:给出两个字符串,再给出一个k,问两个字符串中长度大于等于k的公共子串有多少个(种类可重复) 题目分析:因为涉及到了子串问题,先用后缀数组跑出height数组来,接下来如果 ...
- POJ 1458 Common Subsequence DP LCS 最长公共子序列
最长公共子序列,照抄<算法设计与分析导论>P138-140 设输入的两个字符串分别为a1,a2,```,am(串a) b1,b2,````,bn(串b) 设d(i,j)为字符串a1,a2, ...
- POJ 3415 后缀数组+单调栈
题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...
- POJ 3415 (后缀数组)
被虐残了T_T.开始没思路,膜拜大牛的思路又看不懂...推荐一个题解:http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6 ...
- 【POJ3415】 Common Substrings (SA+单调栈)
这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了... 解法参考论文以及下面的链接 http://www.cnblogs.com/vongang/archive/2012/11/20 ...
- POJ题目分类(按初级\中级\高级等分类,有助于大家根据个人情况学习)
本文来自:http://www.cppblog.com/snowshine09/archive/2011/08/02/152272.spx 多版本的POJ分类 流传最广的一种分类: 初期: 一.基本算 ...
- 《挑战程序设计竞赛(第2版)》习题册攻略
本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...
- kuangbin带你飞专题合集
题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...
最新文章
- python实践3:cursor() — 数据库连接操作
- UA SIE545 优化理论基础 例题 对偶函数的凸性与次梯度计算
- DataGridView怎样实现添加、删除、上移、下移一行
- git 入门教程之版本管理
- matlab波导色散,有效折射率法求矩形波导色散曲线(附Matlab程序)
- 免费JS富文本编辑器 总有一款会适合你
- 大华(华瑞)MVP网络通讯教程实例
- R语言获取国内的股票数据
- linux libata初始化分析
- android 2k屏分辨率是多少,5.5英寸2K分辨率2.5D屏幕
- bugku never give up
- linux qt 获取u盘名称,QT windows平台下获取U盘 QComboBox显示U盘盘符
- R机器学习:分类算法之判别分析LDA,QDA的原理与实现
- 计算机科学与工程一直火,薪火相传(三)|王采玉:一个渺小如蝼蚁的大学生的成长历程...
- oj 中G++和C++区别
- 三种实现Android主界面Tab的方式
- 【CSRF02】跨站请求伪造——DVWA靶场实操(含CSRF+XSS协同攻击实验)
- Windows下Qt使用htons,htonl,ntohs,ntohl
- MATLAB通信系统仿真(三)——扩频通信
- 数据仓库的概念与设计