ZOJ 10th Anniversary Contest - G
#include<string.h> #include<stdio.h> char s1[200000],s2[200000],s3[200000],s4[200000]; long long a[200000],p[200000],q[200000],num[200000],v[200000]; int main() { int t,n,m,i,j,k; scanf("%d",&t); while (t-->0) { scanf(" %s",s1); scanf(" %s",s2); n=strlen(s1); m=strlen(s2); long long ans=0; for (i=0; i<n; i++) {num[i]=0; a[i]=0; p[i]=0; q[i]=0;} p[0]=-1; s4[0]=s2[m-1]; for (i=1; i<m; i++) { p[i]=-1; int k=p[i-1]; while ((k>-1)&&(s2[k+1]!=s2[i])) k=p[k]; if (k>-1) p[i]=k+1; if ((k==-1)&&(s2[0]==s2[i])) p[i]=0; s4[i]=s2[m-i-1]; } int mark=-1; for (i=0; i<n; i++) { while (mark!=-1) { if (s1[i]==s2[mark+1]) break; mark=p[mark]; } if (mark!=-1) {mark++; num[mark]++;} else if (s1[i]==s2[0]) {mark=0; num[mark]++;} a[i]=mark; s3[i]=s1[n-i-1]; if (mark==m-1) mark=p[mark]; } q[0]=-1; for (i=1; i<m; i++) { q[i]=-1; int k=q[i-1]; while ((k>-1)&&(s4[k+1]!=s4[i])) k=q[k]; if ((k==-1)&&(s4[i]==s4[0])) q[i]=0; if (k>-1) q[i]=k+1; } mark=-1; for (i=m-1; i>=0; i--) if (p[i]!=-1) num[p[i]]+=num[i]; for (i=0; i<m; i++) { v[i]=num[m-i-2]; if (q[i]!=-1) v[i]+=v[q[i]]; } for (i=0; i<n; i++) { while (mark!=-1) { if (s3[i]==s4[mark+1]) break; mark=q[mark]; } if (mark!=-1) mark++; else if (s3[i]==s4[0]) mark=0; ans+=v[mark]; if (mark==m-1) mark=q[mark]; } printf("%lld\n",ans); } return 0; }