Common Substrings

后缀数组+单调栈
题解1
题解2
题解3

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
// sa[i]: 排名是i位的是第几个后缀
// rk[i]: 第i个后缀的排名是多少
// height[i]: sa[i]与sa[i-1]
const int N=200010;
char s[N],s1[N],s2[N];
int rk[N],sa[N],cnt[N],height[N];
int x[N],y[N];
int n,m,K;
int n1,n2;
void rsort()// x[i] 第一关键字 y[i] 第二关键字 基数排序
{for(int i=1;i<=m;i++) cnt[i]=0;for(int i=1;i<=n;i++) cnt[x[i]]++;for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];for(int i=n;i;i--) sa[cnt[x[y[i]]]--]=y[i];
}
void SA()
{n=strlen(s+1);m=300;for(int i=1;i<=n;i++) x[i]=s[i],y[i]=i;rsort();for(int k=1;k<=n;k<<=1){int p=0;for(int i=n-k+1;i<=n;i++) y[++p]=i;// 第二关键字为空字符排在最前面for(int i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;rsort();swap(x,y);x[sa[1]]=1,p=1;for(int i=2;i<=n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p);if(p==n) break;m=p;}for(int i=1;i<=n;i++) rk[sa[i]]=i;// 求heightfor(int i=1,j=0;i<=n;i++){if(j) --j;while(s[i+j]==s[sa[rk[i]-1]+j]) j++;height[rk[i]]=j;}
}
int init()
{n1=strlen(s1+1);n2=strlen(s2+1);for(int i=1;i<=n1;i++) s[i]=s1[i];s[n1+1]='*';for(int i=1;i<=n2;i++) s[i+n1+1]=s2[i];s[n1+n2+1+1]='\0';return (n1+n2+1);
}
int st[N][2];
ll solve()
{ll ans=0,tot=0;//当前栈里的后缀与将要入栈的后缀的公共字串的个数// A前 B后int tt=0;for(int i=1;i<=n;i++){if(height[i]<K){tt=0,tot=0;continue;}int cnt=0;// 与以后入栈的序列lcp是height[i]的数目if(sa[i-1]<=n1) // 属于第一个字符串{cnt++;tot+=height[i]-K+1;}while(tt&&height[i]<=st[tt][0]){tot-=1ll*(st[tt][0]-height[i])*st[tt][1];// 由于更小的height[i]导致原先栈中的lcp多算st[tt][0]-height[i]cnt+=st[tt][1];tt--;}st[++tt][0]=height[i];st[tt][1]=cnt;if(sa[i]>n1+1) ans+=tot;// 属于第二个字符串}// B前 A后tt=0;for(int i=1;i<=n;i++){if(height[i]<K){tt=0,tot=0;continue;}int cnt=0;if(sa[i-1]>n1+1) // 属于第一个字符串{cnt++;tot+=height[i]-K+1;}while(tt&&height[i]<=st[tt][0]){tot-=1ll*(st[tt][0]-height[i])*st[tt][1];cnt+=st[tt][1];tt--;}st[++tt][0]=height[i];st[tt][1]=cnt;if(sa[i]<=n1+1) ans+=tot;// 属于第二个字符串}return ans;
}
int main()
{while(scanf("%d",&K),K){scanf("%s%s",s1+1,s2+1);n=init();SA();printf("%lld\n",solve());}return 0;
}

POJ - 3415 Common Substrings(长度不小于K的公共子串个数)相关推荐

  1. 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 ...

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

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

  3. cdoj915-方老师的分身 II (长度不小于k的最短路)【spfa】

    http://acm.uestc.edu.cn/#/problem/show/915 方老师的分身 II Time Limit: 10000/5000MS (Java/Others)     Memo ...

  4. poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)

    题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...

  5. hdu5056(找相同字母不出现k次的子串个数)

    题意:      给你一个字符串,然后问你这个字符串里面有多少个满足要求的子串,要求是每个子串相同字母出现的次数不能超过k. 思路:      这种题目做着比较有意思,而且不是很难(但自己还是嘚瑟,w ...

  6. 【HDU - 4417】Super Mario(查询区间小于K的数的个数,主席树)

    题干: Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded ...

  7. 【POJ3415】 Common Substrings (SA+单调栈)

    这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了... 解法参考论文以及下面的链接 http://www.cnblogs.com/vongang/archive/2012/11/20 ...

  8. POJ 3415 后缀数组+单调栈

    题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...

  9. 最长公共子串LCS (Longest Common Subsequence) 算法

    三个方法都有所借鉴,但代码部分是自己试着写出来的,虽然最后的运行结果都是正确的,但此过程中难免会有考虑不周全的地方,如发现代码某些地方有误,欢迎指正.同时有新的想法,也可以提出! 采用顺序结构存储串, ...

最新文章

  1. 【Android 启动过程】Activity 启动源码分析 ( Activity -> AMS、主线程阶段 )
  2. C 语言 链表的创建与打印
  3. 读写xml节点的数据总结
  4. java mesos kubernete_Fabric8操作Kubernetes(一)
  5. 软考数据库系统工程师第四版考点更新
  6. 匿名mahony互补滤波代码详解
  7. 明日之后怎么在电脑上玩 明日之后电脑版图文攻略
  8. aspose.words 操作 word 文档-文字替换、删除首行、添加水印等方案
  9. zblog host php,zblog获取当前页面的URL信息
  10. Android中3D gallary的实现
  11. Vue 6. 列表渲染
  12. CSS传统布局所用的元素
  13. SDCC教程(树莓派 Debian11 bullseye 使用官方下载源)
  14. 阿里大鱼短信接口教程php,ECSHOP短信接口【ECSHOP阿里大鱼短信】ECSHOP短信插件手机短信服务设置教程-ECSHOP教程网...
  15. HTML代码转word!亲测!可用!!!
  16. 管家婆软件报错:保存失败,请稍后重试。
  17. 在百度地图上开启 测距的功能
  18. 组合数学 | 排列与组合
  19. 公共基础知识:元杂剧之“四大悲剧”
  20. 实名认证接口 实名制API

热门文章

  1. ecshop goods.php,重命名ecshop的商品页goods.php为shangpin.php
  2. java富文本如何转义_富文本编辑器wangEditor中转义字符的问题
  3. java awt区域_java的awt包中有没有表示区域的类或者方法,可以传递一个Rectangle
  4. java emoji编码转换_java转换emoji表情
  5. docker 安装kafka_laradock 中如何安装 Laravel Dusk
  6. 大气校正后的ndvi_大气校正常见错误处理方法及校正后检查
  7. android中的帧动画,[Android开发] Android中的帧动画
  8. 数据结构——从叶子结点到根节点的全部路径
  9. 数据结构——二叉树的层次遍历进阶
  10. Java Number Math 类方法