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");
    }
}
posted @ 2020-01-21 15:03  Shiina_Mashiro  阅读(122)  评论(0编辑  收藏  举报