First through the hash of the achievements
F[I][J] means that the first special symbol begins with the J-bit of p to reach where
Memory search, for the underlying greedy match.
#include <cstdio> #include <cstring>using std::strlen;const int N=510,m=2010;char a[10],tmp[10],b[n][10], S[m];int T,n,m,i,j,k,h[n],son[n][2],len[n],f[n][m];inline int hash (char a[]) {int T=0,j=strlen (a); for (int i=0;i<5;i++) t=t*27+ (i<j? a[i]-' A ' + 1): 0); return t;} int F (int x,int y) {if (~f[x][y]) return f[x][y]; if (Son[x][0]) return f[x][y]=f (Son[x][1],f (son[x][0],y)); int j=y; for (int i=0;j<m&&i<len[x];i++) if (B[x][i]==s[j]) j + +; return f[x][y]=j;} int main () {for (scanf ("%d", &t); t--;p UTS (F (j,0) <m? " NO ":" Yes ") {scanf ("%d ", &n); for (i=1;i<=n;i++) {scanf ("%s%s%s", A,tmp,b[i]), H[i]=hash (a); if (b[i][0]>= ' a ' &&b[i][0]<= ' Z ') Son[i][0]=0,len[i]=strlen (B[i]); else Son[i][0]=hash (B[i]), scanf ("%s", TMP), scanf ("%s", TMP), Son[i][1]=hash (TMP); } for (i=1;i<=n;i++) if (Son[i][0]) for (j=0;j<2;j++) for (k=1;k<=n;k++) if (Son[i][j]==h[k]) {Son[i][j]=k;break ;} scanf ("%s%s", A,s), M=strlen (s); for (i=1;i<=n;i++) for (j=0;j<=m;j++) F[i][j]=-1; For (I=hash (a), k=1;k<=n;k++) if (I==h[k]) {j=k;break;} } return 0;}
BZOJ4060: [Cerc2012]word equations