Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 10850 | Accepted: 3587 |
Description
A substring of a string T is defined as:
Given two strings A, B and one integer K, we define S, a set of triples (i, 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
Source
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define MAXN 200100
int n,k,m,lens;
long long ans=0;
string s,t;
int sa[MAXN],lcp[MAXN];
int rank[MAXN*2],tmp[MAXN*2];
void construct_lcp(string s,int sa[],int lcp[])
{
int n=s.length();
for(int i=0; i<=n; ++i)
rank[sa[i]]=i;
int h=0;
lcp[0]=0;
for(int i=0; i0) --h;
for(; j+h1)
{
int c=(a+b)/2;
if(s.compare(sa[c],t.length(),t)<0) a=c;
else b=c;
}
return s.compare(sa[b],t.length(),t)==0;
}
void solve()
{
int dull[MAXN][2];//维护后缀的单调递减栈,栈顶最小,dull[i][0]是lcp[i],dull[i][1]是个数
long long temp,top;//temp记录当前栈中所有项和一个刚进入的子串匹配所能得到的总的子串的数目
ans=0;
//第一次扫描,B串中的子串匹配rank比其高的A子串
for(int i=0; i0&&lcp[i]<=dull[top-1][0])//调整单调栈,当前最长公共前缀长度比栈顶元素还小
{
--top;
temp-=dull[top][1]*(dull[top][0]-lcp[i]);//去掉出栈元素多加了的个数
res+=dull[top][1];
}
dull[top][0]=lcp[i];
dull[top++][1]=res;
if(sa[i+1]>lens)//在第二个串中,即分属于两个不同字符串
ans+=temp;
}
}
//第二次扫描,A串中的子串匹配rank比其高的B子串
for(int i=0; ilens)//在第二个串中
{
++res;
temp+=lcp[i]-m+1;
}
while (top>0&&lcp[i]<=dull[top-1][0])
{
--top;
temp-=dull[top][1]*(dull[top][0]-lcp[i]);
res+=dull[top][1];
}
dull[top][0]=lcp[i];
dull[top++][1]=res;
if(sa[i+1]>m)
{
if(m==0) break;
cin>>s;
cin>>t;
lens=s.length();
s+='$'+t;//连接串
n=s.length();
construct_sa(s,sa);
construct_lcp(s,sa,lcp);
solve();
cout<