P3618 误会

一看就是哈希+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]);
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号