zoukankan      html  css  js  c++  java
  • [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)

    显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行。

    一次一起转移两个通配符之间的所有字符,Hash判断。

    稍微有点细节。常数极大卡时过排名倒数,可能是没自然溢出的原因。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 using namespace std;
     6 
     7 const int N=200010,p1=133,p2=7393913;
     8 bool f[20][N];
     9 char s1[N],s2[N];
    10 int n,m,T,tot,pos[20],h1[N],h2[N],pw[N];
    11 
    12 int main(){
    13     freopen("bzoj3507.in","r",stdin);
    14     freopen("bzoj3507.out","w",stdout);
    15     scanf("%s",s1+1); n=strlen(s1+1)+1; s1[n]='?';
    16     pw[0]=1; rep(i,1,n) pw[i]=1ll*pw[i-1]*p1%p2;
    17     rep(i,1,n) h1[i]=(1ll*h1[i-1]*p1+s1[i])%p2;
    18     rep(i,1,n) if (s1[i]=='?' || s1[i]=='*') pos[++tot]=i;
    19     for (scanf("%d",&T); T--; ){
    20         scanf("%s",s2+1); m=strlen(s2+1)+1; s2[m]='#';
    21         rep(i,0,tot) rep(j,0,m) f[i][j]=0; f[0][0]=1;
    22         rep(i,1,m) h2[i]=(1ll*h2[i-1]*p1+s2[i])%p2;
    23         rep(i,0,tot) rep(j,0,m){
    24             if (s1[pos[i]]=='*') f[i][j]|=f[i][j-1];
    25             if (!f[i][j]) continue;
    26             int l1=pos[i]+1,r1=pos[i+1]-1,l2=j+1,r2=j+(pos[i+1]-pos[i])-1;
    27             if ((h1[r1]-1ll*h1[l1-1]*pw[r1-l1+1]%p2+p2)%p2==(h2[r2]-1ll*h2[l2-1]*pw[r2-l2+1]%p2+p2)%p2){
    28                 if (s1[pos[i+1]]=='?') f[i+1][r2+1]|=f[i][j]; else f[i+1][r2]|=f[i][j];
    29             }
    30         }
    31         puts(f[tot][m] ? "YES" : "NO");
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    hrbust1279
    U盘快捷方式中毒处理办法
    计算几何
    poj1113
    凸包模版
    STL容器
    HDU2048
    HDU2047
    HDU2045
    python面试题总结
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10273037.html
Copyright © 2011-2022 走看看