Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 9414   Accepted: 3123

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

题意:给你2个字符串,让你分别在两个字符串中找到一个相同的子串,并且这两个相同串的长度要大于等于k,求这样的子串个数。

思路:这题思路不好想啊。我们知道,一个字符串的子串可以由母串的一个后缀的前缀表示,所以题目就变为求A中所有后缀的前缀和B中所有后缀的前缀公共前缀长度大于等于k的对数。我们可以把两个串连接起来,并且在两个串的中间插入一个以前没有出现过的字符(注意:这个字符的大小不能是0,即不能和最后一个我们自己添加的字符的大小相同,不然会错 = =),然后先求出sa[],height[]。按height[]值分组后,接下来的工作便是快速的统计每组中后缀之间的最长公共前缀之和。扫描一遍,每遇到一个B的后缀就统计与前面的A 的后缀能产生多少个长度不小于k 的公共子串,这里A 的后缀需要用一个单调的栈来高效的维护,然后对A也这样做一次。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define M 100050
#define maxn 200050
char s1[M],s2[M];
int sa[maxn],a[maxn];
int wa[maxn],wb[maxn],wv[maxn],we[maxn];
int rk[maxn],height[maxn];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void build_sa(int *r,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=0;i<m;i++)we[i]=0;
for(i=0;i<n;i++)we[x[i]=r[i]]++;
for(i=1;i<m;i++)we[i]+=we[i-1];
for(i=n-1;i>=0;i--)sa[--we[x[i]]]=i;
for(j=1,p=1;p<n;j*=2,m=p){
for(p=0,i=n-j;i<n;i++)y[p++]=i;
for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=0;i<n;i++)wv[i]=x[y[i]];
for(i=0;i<m;i++)we[i]=0;
for(i=0;i<n;i++)we[wv[i]]++;
for(i=1;i<m;i++)we[i]+=we[i-1];
for(i=n-1;i>=0;i--)sa[--we[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
} void calheight(int *r,int n)
{
int i,j,k=0;
for(i=1;i<=n;i++)rk[sa[i]]=i;
for(i=0;i<n;height[rk[i++] ]=k){
for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
}
}
int q[111111][3]; //0表示高度,1表示宽度,2表示时间 int main()
{
int n,m,i,j,k;
int front,rear,len1,len2;
ll sum,kuan,tot; //sum表示最后的答案,kuan表示单调队列里面每一个元素的宽度
while(scanf("%d",&k)!=EOF && k!=0)
{
scanf("%s%s",s1,s2);
n=0;
len1=strlen(s1);
len2=strlen(s2);
for(i=0;i<len1;i++){
a[n++]=s1[i]-'a'+98;
}
a[n++]=1;
for(i=0;i<len2;i++){
a[n++]=s2[i]-'a'+98;
}
a[n]=0;
build_sa(a,n+1,130);
calheight(a,n); sum=0;
for(i=1;i<=n;i++){
if(height[i]<k){
front=1,rear=0;
tot=0; //tot表示所有面积和
continue;
}
kuan=0;
while(front<=rear && q[rear][0]>=height[i]){
kuan+=q[rear][1];
tot-=q[rear][1]*(q[rear][0]-height[i]);
rear--;
}
if(sa[i-1]<len1){
kuan++;
tot+=height[i]-k+1;
}
rear++;
q[rear][0]=height[i];q[rear][1]=kuan;
if(sa[i]>len1){
sum+=tot;
}
} for(i=1;i<=n;i++){
if(height[i]<k){
front=1,rear=0;
tot=0; //tot表示所有面积和
continue;
}
kuan=0;
while(front<=rear && q[rear][0]>=height[i]){
kuan+=q[rear][1];
tot-=q[rear][1]*(q[rear][0]-height[i]);
rear--;
}
if(sa[i-1]>len1){
kuan++;
tot+=height[i]-k+1;
}
rear++;
q[rear][0]=height[i];q[rear][1]=kuan;
if(sa[i]<len1){
sum+=tot;
}
}
printf("%lld\n",sum);
}
return 0;
}

poj3415 Common Substrings (后缀数组+单调队列)的更多相关文章

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

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

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

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

  3. poj 3415 Common Substrings——后缀数组+单调栈

    题目:http://poj.org/problem?id=3415 因为求 LCP 是后缀数组的 ht[ ] 上的一段取 min ,所以考虑算出 ht[ ] 之后枚举每个位置作为右端的贡献. 一开始想 ...

  4. poj 3415 Common Substrings —— 后缀数组+单调栈

    题目:http://poj.org/problem?id=3415 先用后缀数组处理出 ht[i]: 用单调栈维护当前位置 ht[i] 对之前的 ht[j] 取 min 的结果,也就是当前的后缀与之前 ...

  5. poj 3415 Common Substrings 后缀数组+单调栈

    题目链接 题意:求解两个字符串长度 大于等于k的所有相同子串对有多少个,子串可以相同,只要位置不同即可:两个字符串的长度不超过1e5; 如 s1 = "xx" 和 s2 = &qu ...

  6. hihoCoder 1403 后缀数组一·重复旋律(后缀数组+单调队列)

    #1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...

  7. BZOJ_4698_Sdoi2008 Sandy的卡片_后缀数组+单调队列+双指针

    BZOJ_4698_Sdoi2008 Sandy的卡片_后缀数组 Description Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是 ...

  8. POJ 3261 Milk Patterns(后缀数组+单调队列)

    题意 找出出现k次的可重叠的最长子串的长度 题解 用后缀数组. 然后求出heigth数组. 跑单调队列就行了.找出每k个数中最小的数的最大值.就是个滑动窗口啊 (不知道为什么有人写二分,其实写啥都差不 ...

  9. POJ - 3415 Common Substrings (后缀数组)

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

随机推荐

  1. 【JavaWeb】Servlet 程序

    Servlet 程序 Servlet Servlet 是在 Web 服务器中运行的小型 Java 程序.Servlet 通常通过 HTTP(超文本传输​​协议)接收和响应来自 Web 客户端的请求. ...

  2. DG主备切换遇到not allwod或者RESOLVABLE GAP解决办法

    今天做switchover,环境是11.2.0.3+OEL5.7,开始时主备库状态都是正常的,符合直接切换条件: 主库: SQL> select open_mode,database_role, ...

  3. CTF实验吧-WEB题目解题笔记(1)简单的登陆题

    1.简单的登陆题 解题链接: http://ctf5.shiyanbar.com/web/jiandan/index.php  Burp抓包解密 乱码,更换思路.尝试id intruder 似乎也没什 ...

  4. Kubernetes CoreDNS 状态是 CrashLoopBackOff 报错

    查看状态的时候,遇见coredns出现crashlookbackoff,首先我们来进行排错,不管是什么原因,查看coredns的详细信息,以及logs [root@k8s-master coredns ...

  5. git创建分支并关联远程分支

    1.新建本地分支: 如图,再输入你的分支名字,然后选择从哪个远程分支拉代码,如选择master 至此本地分支创建完成. 2.关联远程分支: (1).先输入git branch -vv,看看分支与远程分 ...

  6. MongoDB分片集群部署方案

    前言 副本集部署是对数据的冗余和增加读请求的处理能力,却不能提高写请求的处理能力:关键问题是随着数据增加,单机硬件配置会成为性能的瓶颈.而分片集群可以很好的解决这一问题,通过水平扩展来提升性能.分片部 ...

  7. 20V,24V转5V,20V,24V转3.3V降压芯片,IC介绍

    常用的20V和24V转5V,3.3V的LDO稳压和DC-DC降压芯片: PW6206系列是一款高精度,高输入电压,低静态电流,高速,低压降线性稳压器具有高纹波抑制.输入电压高达40V,负载电流高达10 ...

  8. 配置Charles 设置手机代理并允许https请求

    前言: 在h5开发调试时,为实现手机app访问localhost地址,可以使用ip地址的方式,但一般公司app出于安全考虑,会限制只能访问其自有域名.因此,使用charles代理的方式 步骤 用手机代 ...

  9. 事件循环Event loop到底是什么

    摘要:本文通过结合官方文档MDN和其他博客深入解析浏览器的事件循环机制,而NodeJS有另一套事件循环机制,不在本文讨论范围中.process.nextTick和setImmediate是NodeJS ...

  10. Python+Selenium+Unittest实现PO模式web自动化框架(8)

    1.main.py模块的功能 最后就是要有一个项目入口,并且是需要加载测试用例集. # --^_^-- coding:utf-8 --^_^-- # @Remark:运行入口 "" ...