D - Common Substrings
Crawling in process...
Crawling failed
Time Limit:5000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Appoint description:
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
思路:
#include<iostream> #include<cstring> #include<cstdio> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) using namespace std; const int msize=2e5+9; class SUFFIX_ARRAY { public: int sa[msize],h[msize],rank[msize],t1[msize],c[msize]; bool cmp(int*r,int i,int k) { return r[ sa[i] ]==r[ sa[i-1] ]&&r[ sa[i]+k ]==r[ sa[i-1]+k ]; } void build_SA(int*s,int n,int m) { int*wx=t1,*wy=rank; FOR(i,0,m-1)c[i]=0; FOR(i,0,n-1)++c[ wx[i]=s[i] ]; FOR(i,1,m-1)c[i]+=c[i-1]; for(int i=n-1;i>=0;--i)sa[ --c[ wx[i] ] ]=i; for(int k=1;k<=n;k<<=1) { int p=0; FOR(i,n-k,n-1)wy[p++]=i; FOR(i,0,n-1)if(sa[i]>=k)wy[p++]=sa[i]-k; FOR(i,0,m-1)c[i]=0; FOR(i,0,n-1)++c[ wx[ wy[i] ] ]; FOR(i,1,m-1)c[i]+=c[i-1]; for(int i=n-1;i>=0;--i)sa[ --c[ wx[ wy[i] ] ] ]=wy[i]; swap(wx,wy); wx[ sa[0] ]=0;p=1; FOR(i,1,n-1)wx[ sa[i] ]=cmp(wy,i,k)?p-1:p++; if(p>=n)break; m=p; } } void get_H(int*s,int n) { int k=0; FOR(i,0,n)rank[ sa[i] ]=i; FOR(i,0,n-1) { if(k)--k; int j=sa[ rank[i]-1 ]; while(s[i+k]==s[j+k])++k; h[ rank[i] ]=k; } } void debug(int n) { printf("sa="); FOR(i,0,n)printf("%d ",sa[i]);puts(""); printf("rank="); FOR(i,0,n)printf("%d ",rank[i]);puts(""); printf("h="); FOR(i,0,n)printf("%d ",h[i]);puts(""); } }; SUFFIX_ARRAY ty; int len; int r[msize]; char s1[msize],s2[msize]; int sta[msize],stb[msize]; int main() { while(scanf("%d",&len)&&len) { scanf("%s%s",s1,s2); int len1=strlen(s1); int len2=strlen(s2); int len3=0; for(int i=0;s1[i];++i) r[i+len3]=s1[i]; r[len3+len1]=128; len3+=len1+1; for(int i=0;s2[i];++i) r[ i+len3 ]=s2[i]; r[ len3+len2 ]=129; len3+=len2+1; r[len3]=0; ty.build_SA(r,len3+1,300); ty.get_H(r,len3); // ty.debug(len3-1); long long ans=0; long long ss=0; int top=0; for(int i=2;i<=len3;i++) { if(ty.h[i]<len) { ss=0; top=0; continue; } int cnt=0; if(ty.sa[i-1]<len1) { cnt++; ss+=ty.h[i]-len+1; } while(top>0 && ty.h[i]<=sta[top-1]) { top--; ss-=stb[top]*(sta[top]-ty.h[i]); cnt+=stb[top]; } sta[top]=ty.h[i];stb[top++]=cnt; if(ty.sa[i]>len1)ans+=ss; } ss=0;top=0; for(int i=2;i<=len3;i++) { if(ty.h[i]<len) { ss=0; top=0; continue; } int cnt=0; if(ty.sa[i-1]>len1) { cnt++; ss+=ty.h[i]-len+1; } while(top>0 && ty.h[i]<=sta[top-1]) { top--; ss-=stb[top]*(sta[top]-ty.h[i]); cnt+=stb[top]; } sta[top]=ty.h[i];stb[top++]=cnt; if(ty.sa[i]<len1)ans+=ss; } printf("%I64d\n",ans); } }