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
对第一个串建立自动机,然后让第二个串在上面跑,记录一下到每个状态时的匹配的长度,一个状态是很多后缀串的集合,我们只需要当前状态中大于等于K 小于等于匹配长度的串然后如果fa有长度也大于等于k的串的话,那也可以去为了避免每次都要向上找fa,打一个lazy标记一波,最后在一遍更新就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define ri register int 6 using namespace std; 7 const int N=2e5+5; 8 typedef long long ll; 9 int k,n; 10 char s[N]; 11 inline int calc(char c){return c>=‘a‘&&c<=‘z‘?c-‘a‘:c-‘A‘+26;} 12 struct SAM{ 13 int tot,rt,last,len[N],link[N],son[N][60],siz[N],lz[N],cnt[N],rk[N]; 14 inline void init(){ 15 memset(len,0,sizeof(len)),memset(siz,0,sizeof(siz)),memset(rk,0,sizeof(rk)),memset(son,0,sizeof(son)); 16 memset(link,0,sizeof(link)),memset(cnt,0,sizeof(cnt)),memset(lz,0,sizeof(lz)),tot=last=rt=1,len[0]=-1; 17 } 18 inline void expend(int x){ 19 int p=last,np=++tot; 20 siz[last=np]=1,len[np]=len[p]+1; 21 while(p&&!son[p][x])son[p][x]=np,p=link[p]; 22 if(!p){link[np]=rt;return;} 23 int q=son[p][x],nq; 24 if(len[q]==len[p]+1){link[np]=q;return;} 25 len[nq=++tot]=len[p]+1,memcpy(son[nq],son[q],sizeof(son[q])),link[nq]=link[q]; 26 while(p&&son[p][x]==q)son[p][x]=nq,p=link[p]; 27 link[q]=link[np]=nq; 28 } 29 inline void topsort(){ 30 for(ri i=1;i<=tot;++i)++cnt[len[i]]; 31 for(ri i=1;i<=last;++i)cnt[i]+=cnt[i-1]; 32 for(ri i=1;i<=tot;++i)rk[cnt[len[i]]--]=i; 33 for(ri i=tot;i;--i)siz[link[rk[i]]]+=siz[rk[i]]; 34 } 35 inline void query(){ 36 topsort(); 37 int p=1,nowlen=0; 38 ll ans=0; 39 for(ri i=1;i<=n;++i){ 40 int x=calc(s[i]); 41 if(son[p][x])p=son[p][x],++nowlen; 42 else{ 43 while(p&&!son[p][x])p=link[p]; 44 if(!p)p=1,nowlen=0; 45 else nowlen=len[p]+1,p=son[p][x]; 46 } 47 if(nowlen>=k){ 48 ans+=(ll)(nowlen-max(k,len[link[p]]+1)+1)*siz[p]; 49 if(len[link[p]]>=k)++lz[link[p]]; 50 } 51 } 52 for(ri i=tot;i;--i){ 53 p=rk[i]; 54 ans+=(ll)lz[p]*siz[p]*(len[p]-max(k,len[link[p]]+1)+1); 55 if(len[link[p]]>=k)lz[link[p]]+=lz[p]; 56 } 57 cout<<ans<<‘\n‘; 58 } 59 }sam; 60 int main(){ 61 while(scanf("%d",&k),k){ 62 scanf("%s",s+1),n=strlen(s+1),sam.init(); 63 for(ri i=1;i<=n;++i)sam.expend(calc(s[i])); 64 scanf("%s",s+1),n=strlen(s+1),sam.query(); 65 } 66 return 0; 67 }
原文地址:https://www.cnblogs.com/zhangbuang/p/10886323.html
时间: 2024-09-30 11:14:39