codeforces 494B

题解:

先用hash或者KMP预处理匹配位置;

考虑dp[i]表示以i结尾的方案数,如果 [ i-m+1 , i ]不能匹配上,那么 dp[i]=dp[i-1]

否则dp[i]=(i-m+1)+sum[i-m]+sum[i-m-1]+……+sum[0] (前面部分是新开一个串,后面表示接一个串上去)

维护前缀和、前缀和的前缀和,转移O(1)

 1 #include<bits/stdc++.h>
 2 #define maxn 100005
 3 #define ll long long
 4 using namespace std;
 5 int n,m;
 6 char a[maxn],b[maxn];
 7 const ll bas1=37,bas2=131;
 8 const ll mod1=998244353,mod2=1000000009;
 9 ll h1[maxn],xp1[maxn],h2[maxn],xp2[maxn];
10 ll H1,H2;
11 void pre()
12 {
13     xp1[0]=1;xp2[0]=1;
14     for(int i=1;i<=n;++i)xp1[i]=xp1[i-1]*bas1%mod1;
15     for(int i=1;i<=n;++i)xp2[i]=xp2[i-1]*bas2%mod2;
16     for(int i=1;i<=n;++i)h1[i]=(h1[i-1]*bas1%mod1+a[i]-'0')%mod1;
17     for(int i=1;i<=n;++i)h2[i]=(h2[i-1]*bas2%mod2+a[i]-'0')%mod2;
18     for(int i=1;i<=m;++i)H1=(H1*bas1%mod1+b[i]-'0')%mod1;
19     for(int i=1;i<=m;++i)H2=(H2*bas2%mod2+b[i]-'0')%mod2;
20 }
21 ll gethash1(int l,int r)
22 {
23     return (h1[r]-h1[l-1]*xp1[r-l+1]%mod1+mod1)%mod1;
24 }
25 ll gethash2(int l,int r)
26 {
27     return (h2[r]-h2[l-1]*xp2[r-l+1]%mod2+mod2)%mod2;
28 }
29 bool issame(int l,int r)
30 {
31     return (gethash1(l,r)==H1)&&(gethash2(l,r)==H2);
32 }
33 const ll mod = 1000000007;
34 ll dp[maxn],s1[maxn],s2[maxn];
35 int main()
36 {
37     scanf("%s%s",a+1,b+1);
38     n=strlen(a+1),m=strlen(b+1);
39     pre();
40     for(int l=1,r=m;r<=n;++l,++r)
41     {
42         if(!issame(l,r))dp[r]=dp[r-1];
43         else dp[r]=(l+s2[l-1])%mod;
44         s1[r]=s1[r-1]+dp[r];s1[r]%=mod;
45         s2[r]=s2[r-1]+s1[r];s2[r]%=mod;
46     }
47     printf("%I64d
",s1[n]);
48     return 0;
49 }
View Code
原文地址:https://www.cnblogs.com/uuzlove/p/10454328.html