您的位置:首页 > 其它

POJ 3415 Common Substrings (求长度大于K的公共子串个数,5级)

2013-09-10 18:48 429 查看
D - Common SubstringsCrawling in process...Crawling failedTime Limit:5000MSMemory Limit:65536KB 64bit IO Format:%I64d & %I64uSubmitStatusAppoint description:System Crawler (2013-08-31)DescriptionA 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 defineS, 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 andK.InputThe input file contains several blocks of data. For each block, the first line contains one integerK, followed by two lines containing strings A and B, respectively. The input file is ended byK=0.1 ≤ |A|, |B| ≤ 1051 ≤ K ≤ min{|A|, |B|}Characters of A and B are all Latin letters.OutputFor 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);}}
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐