您的位置:首页 > 其它

poj 3415 Common Substrings(2个字符串大于等于m的子串数量 后缀数组)

2017-09-19 15:54 483 查看
Common Substrings

Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 11375 Accepted: 3760
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


解题报告:http://blog.csdn.net/acm_cxlove/article/details/7946967

因为两个字符串的最大前缀长度等于他们之间的最大前缀的最小值  所以用单调栈维护一个上升的最大前缀长度 更新栈时 减去超过当前最大长度的贡献

扫两次 一次用B去匹配前面的A 一次用A去匹配前面的B

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;
const int N = 1000000+10;
typedef long long LL;
int sa
;
int t1
,t2
,c
;
int rank1
,height
;
void build_sa(int s[],int n,int m)
{
int i,j,p,*x=t1,*y=t2;
for(int i=0; i<m; i++) c[i]=0;
for(int i=0; i<n; i++) c[x[i]=s[i]]++;
for(int i=0; i<m; i++) c[i]+=c[i-1];
for(int i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(j=1; j<=n; j<<=1)
{
p=0;
for(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<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[y[i]]]++;
for(i=0; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1;
x[sa[0]]=0;
for(i=1; i<n; i++)
x[sa[i]]=(y[sa[i-1]]==y[sa[i]])&&(y[sa[i-1]+j]==y[sa[i]+j])?p-1:p++;
if(p>=n) break;
m=p;
}
}
int s
;
void getheight(int s[],int n)
{
int i, j, k=0;
for(i=0; i<=n; i++) rank1[sa[i]]=i;
for(i=0; i<n; i++)
{
if(k) k--;
j=sa[rank1[i]-1];
while(s[i+k]==s[j+k]) k++;
height[rank1[i]]=k;
}
return ;
}
char str
;
LL st
[2];

int main()
{
int m;
while(scanf("%d", &m),m!=0)
{
int n=0;
scanf("%s",str);
int len1=strlen(str);
for(int i=0; i<len1; i++) s[n++]=str[i];
s
='#';
n++;
scanf("%s",str);
int len2=strlen(str);
for(int i=0; i<len2; i++) s[n++]=str[i];
s
=0;
build_sa(s,n+1,300);
getheight(s,n);

int k=0;
LL sum=0, ans=0;

for(int i=1;i<=n;i++)
{
if(height[i]<m)
{
k=0,sum=0;
continue;
}
int cnt=0;
if(sa[i-1]<len1) cnt++,sum+=(height[i]-m+1);
while(k>=1&&height[i]<=st[k][0])
{
cnt+=st[k][1];
sum-=(st[k][1]*(st[k][0]-height[i]));
k--;
}
st[++k][1]=cnt;
st[k][0]=height[i];
if(sa[i]>len1) ans+=sum;
}
sum=0,k=0;
for(int i=1;i<=n;i++)
{
if(height[i]<m)
{
k=0,sum=0;
continue;
}
int cnt=0;
if(sa[i-1]>len1) cnt++,sum+=(height[i]-m+1);
while(k>=1&&height[i]<=st[k][0])
{
cnt+=st[k][1];
sum-=(st[k][1]*(st[k][0]-height[i]));
k--;
}
st[++k][1]=cnt;
st[k][0]=height[i];
if(sa[i]<len1) ans+=sum;
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐