Time Limit: 4 second(s) | Memory Limit: 64 MB |
Bono, a very famous singer, had always wanted to have a machine to turn the melodies into strings. Last month he earned two million dollars and bought one of those amazing machines, suddenly he began to play some solos to test his new toy. Surprisingly this machine was able to take a piece of song and output a string of lowercase characters from 'a' to 'z'. After playing his two best solos he took the resulting strings A and B and began to count substrings and repetitions. He is a great singer but is not good in programming at all, that's why he needs you to help him to find how many distinct substrings of A that don't contain B as a substring.
Input
Input starts with an integer T (≤ 25), denoting the number of test cases.
Each case starts with a line containing string A. The next line contains string B. You can safely assume that the strings are non-empty and none of their length is more than 50000 and they will contain lowercase English alphabets only.
Output
For each case, print the case number and the number of substrings that Bono needs to know.
Sample Input |
Output for Sample Input |
4 ababa ba ababa a abbabaaaba aa ababababa bab |
Case 1: 3 Case 2: 1 Case 3: 15 Case 4: 5 |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAXN 50008
char s1[MAXN],s2[MAXN];
int nex[MAXN],lon;
int num[MAXN];
int r[MAXN],pre[MAXN];
int bucket[MAXN];
int rankx[MAXN],ranky[MAXN];
int sa[MAXN],height[MAXN];
int MIN(int x,int y){ return x<y?x:y; }
void get_next(char *s)
{
int i,j;
nex[0]=j=-1;
for(i=0;s[i];)
{
if(j==-1||s[i]==s[j]) nex[++i]=++j;
else j=nex[j];
}
}
void mycount()
{
int i,k,j=0,now=0;
int len1=strlen(s1),len2=strlen(s2);
for(i=0;i<len1;i++) num[i]=len1-i;
for(i=0;s1[i];)
{
if(j==-1||s1[i]==s2[j]) j++,i++;
else j=nex[j];
if(j==len2)
{
j=nex[j];
for(k=now;k<=i-len2;k++) num[k]=i-1-k;
now=i-len2+1;
}
}
}
int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void suffix_array(int *s,int *sa,int n,int m)
{
int i,j,p,*x=rankx,*y=ranky,*t;
for(i=0;i<m;i++) bucket[i]=0;
for(i=0;i<n;i++) bucket[x[i]=s[i]]++;
for(i=1;i<m;i++) bucket[i]+=bucket[i-1];
for(i=n-1;i>=0;i--) sa[--bucket[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<m;i++) bucket[i]=0;
for(i=0;i<n;i++) bucket[x[y[i]]]++;
for(i=1;i<m;i++) bucket[i]+=bucket[i-1];
for(i=n-1;i>=0;i--) sa[--bucket[x[y[i]]]]=y[i];
t=x,x=y,y=t;
for(p=i=1,x[sa[0]]=0;i<n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
}
void calculate_height(int *r,int *sa,int *x,int *height,int n)
{
int i,j,k=0;
for(i=0;i<=n;i++) x[sa[i]]=i;
for(i=0;i<n;height[x[i++]]=k)
{
for(k?k--:0,j=sa[x[i]-1];r[i+k]==r[j+k];k++);
}
}
int solve()
{
int i,res=0;
for(i=1;i<=lon;i++)
{
res+=num[sa[i]]-MIN(num[sa[i]],height[i]);
}
return res;
}
int main()
{
int t,i,cas=1;
scanf("%d",&t);
while(t--)
{
scanf("%s%s",s1,s2);
lon=strlen(s1);
get_next(s2);
mycount();
for(i=0;i<lon;i++) r[i]=s1[i]-'a'+1;
r[i]=0;
suffix_array(r,sa,lon+1,30);
calculate_height(r,sa,rankx,height,lon);
printf("Case %d: %d\n",cas++,solve());
}
return 0;
}