一看就是哈希+dp
用到哈希是因为要看当前子串和原子串是否匹配 用dp是来统计方案数的
dp[i] 表示前i个字符的方案数
转移方程:
设原串的长度为len
如果匹配(哈希值相等) dp[i]=dp[i-1]+dp[i-len] 表示当前这个子串可以换成*
如果不匹配 dp[i]=dp[i-1];
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int mod=1e9+7;
const int maxn=1e5+5;
const int p=131;
unsigned ll dp[maxn],base[maxn],ha[maxn],g;
int T,tot;
void init(){
base[0]=1;
for(int i=1;i<maxn;i++)base[i]=base[i-1]*p;
return;
}
void solve();
int main(){
init();
cin>>T;
while(T--)solve();
return 0;
}
void solve(){
string s,t;
cin>>s>>t;
s='.'+s;
t='.'+t;
g=0;
dp[0]=1;
for(int i=1;i<s.size();i++)
ha[i]=ha[i-1]*p+(s[i]+0);
for(int i=1;i<t.size();i++)
g=g*p+(t[i]+0);
for(int i=1;i<s.size();i++){
int l=i-(t.size()-1)+1;
if(l>=1){
if((ha[i]-ha[l-1]*base[i-l+1])==g)
dp[i]=(dp[i-1]+dp[l-1])%mod;
else dp[i]=dp[i-1];
}
else dp[i]=dp[i-1];
}
printf("Case #%d: %lld\n",++tot,dp[s.size()-1]);
}