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]);
}
posted @ 2022-04-29 20:12  wzx_believer  阅读(42)  评论(0)    收藏  举报