HDU 5763 Another Meaning
简单dp+KMP。记dp[i]为以0--i能表达的意义种类。
如果以s[i]为结尾的后缀不匹配,那么dp[i]=dp[i-1]。
如果以s[i]为结尾的后缀匹配,那么dp[i]=dp[i-1]+dp[i-len]; (即表达第一种意思的种类数+表达第二种意思的种类数)
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } inline int read() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } LL mod=1000000007; const int maxn=100010; int nx[maxn],f[maxn]; char a[maxn],b[maxn]; int len1,len2; LL ans[maxn]; void get_next() { int j=-1,i=0; nx[0]=-1; while(i<len2) { if(j==-1||b[i]==b[j]) i++, j++, nx[i]=j; else j=nx[j]; } } void kmp(){ get_next(); int i=0,j=0; while(i<len1){ if(j==-1||a[i]==b[j]) i++ ,j++; else j=nx[j]; if(j==len2) f[i-j+len2]=1; } } int main() { int T; scanf("%d",&T); int cas=1; while(T--) { scanf("%s%s",a,b); len1=strlen(a),len2=strlen(b); memset(f,0,sizeof f); kmp(); ans[0]=1; for(int i=1;i<=len1;i++) { ans[i]=ans[i-1]; if(f[i]==1) ans[i]=(ans[i]+ans[i-len2])%mod; } printf("Case #%d: %lld\n",cas++,ans[len1]); } return 0; }