Description

A substring of a string T is defined as:

T(ik)=TiTi+1...Ti+k-1, 1≤ii+k-1≤|T|.

Given two strings AB and one integer K, we define S, a set of triples (ijk):

S = {(ijk) | kKA(ik)=B(jk)}.

You are to give the value of |S| for specific AB 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相关推荐

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

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

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

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

  3. POJ 1458 Common Subsequence DP LCS 最长公共子序列

    最长公共子序列,照抄<算法设计与分析导论>P138-140 设输入的两个字符串分别为a1,a2,```,am(串a) b1,b2,````,bn(串b) 设d(i,j)为字符串a1,a2, ...

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

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

  5. POJ 3415 (后缀数组)

    被虐残了T_T.开始没思路,膜拜大牛的思路又看不懂...推荐一个题解:http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6 ...

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

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

  7. POJ题目分类(按初级\中级\高级等分类,有助于大家根据个人情况学习)

    本文来自:http://www.cppblog.com/snowshine09/archive/2011/08/02/152272.spx 多版本的POJ分类 流传最广的一种分类: 初期: 一.基本算 ...

  8. 《挑战程序设计竞赛(第2版)》习题册攻略

    本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...

  9. kuangbin带你飞专题合集

    题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...

最新文章

  1. python实践3:cursor() — 数据库连接操作
  2. UA SIE545 优化理论基础 例题 对偶函数的凸性与次梯度计算
  3. DataGridView怎样实现添加、删除、上移、下移一行
  4. git 入门教程之版本管理
  5. matlab波导色散,有效折射率法求矩形波导色散曲线(附Matlab程序)
  6. 免费JS富文本编辑器 总有一款会适合你
  7. 大华(华瑞)MVP网络通讯教程实例
  8. R语言获取国内的股票数据
  9. linux libata初始化分析
  10. android 2k屏分辨率是多少,5.5英寸2K分辨率2.5D屏幕
  11. bugku never give up
  12. linux qt 获取u盘名称,QT windows平台下获取U盘 QComboBox显示U盘盘符
  13. R机器学习:分类算法之判别分析LDA,QDA的原理与实现
  14. 计算机科学与工程一直火,薪火相传(三)|王采玉:一个渺小如蝼蚁的大学生的成长历程...
  15. oj 中G++和C++区别
  16. 三种实现Android主界面Tab的方式
  17. 【CSRF02】跨站请求伪造——DVWA靶场实操(含CSRF+XSS协同攻击实验)
  18. Windows下Qt使用htons,htonl,ntohs,ntohl
  19. MATLAB通信系统仿真(三)——扩频通信
  20. 数据仓库的概念与设计

热门文章

  1. jQuery 插件开发实例(二)
  2. 什么是Java实例初始化块
  3. 外文翻译 《How we decide》赛场上的四分卫 第三节
  4. 积木履带机器人编程手册_学会编程,寓教于乐!ONEBOT 反履机甲图赏
  5. 射频领域中交调和互调的区别
  6. 什么是三极管的倒置状态及其作用!
  7. Word文档如何自动生成文献摘要?
  8. “僵尸病毒”入侵全球电脑,7.5万部电脑中招(来源:广州日报)
  9. 半导体二极管的直流电阻和动态电阻如何区别?
  10. pyqt5获取屏幕大小并将窗口大小设置为屏幕的百分之六十