Luogu P3167 [CQOI2014]通配符匹配
Link
设\(f_{i,j}\)表示\(s\)从\(1\)到第\(i\)个通配符是否能匹配\(t_{1\sim j}\)。
然后哈希一下再随便转移一下就好了。
#include<cstdio>
#include<cstring>
using u64=unsigned long long;
const int N=100007;
u64 pw[N],hs[N],ht[N];char s[N],t[N];int f[12][N],pos[12];
int main()
{
int T,len,l,cnt=0;
pw[0]=1;for(int i=1;i<=100000;++i) pw[i]=pw[i-1]*233;
scanf("%s%d",s+1,&T),len=strlen(s+1),s[++len]='?';
for(int i=1;i<=len;++i) hs[i]=hs[i-1]*233+s[i],s[i]=='*'||s[i]=='?'? pos[++cnt]=i:0;
while(T--)
{
scanf("%s",t+1),l=strlen(t+1),t[++l]='!';
for(int i=1;i<=l;++i) ht[i]=ht[i-1]*233+t[i];
memset(f,0,sizeof f),f[0][0]=1;
for(int i=0;i<=cnt;++i)
{
if(s[pos[i]]=='*') for(int j=1;j<=l;++j) f[i][j]|=f[i][j-1];
if(i==cnt) continue;
for(int j=0;j<=l;++j)
{
if(!f[i][j]) continue;
int la=pos[i]+1,ra=pos[i+1]-1,lb=j+1,rb=j+pos[i+1]-pos[i]-1;
if(hs[ra]-hs[la-1]*pw[ra-la+1]==ht[rb]-ht[lb-1]*pw[rb-lb+1]) (s[pos[i+1]]=='?'? f[i+1][rb+1]:f[i+1][rb])=1;
}
}
puts(f[cnt][l]?"YES":"NO");
}
}