Insert each string positive into trie a, and insert trie B backwards.
And find out the DFS sequence of each string in a, B.
Each query is equivalent to querying the number of strings in a DFS sequence between [La,ra] in a, and the DFS sequence in [LB,RB] in B, which is maintained by the Chairman tree.
#include <cstdio>const int S=2000010,n=2010,m=n*22;char s[s],ch;int n,m,i,j,k,posa[n],posb[n],g[s],v[n],nxt[n ],ed,la,lb,ra,rb,ans;inline void Read () {while (! ( ((Ch=getchar ()) >= ' a ') && (ch<= ' z '))); s[k=1]= (ch-' a ' +ans)%26; while (((Ch=getchar ()) >= ' a ') && (ch<= ' z ')) s[++k]= (ch-' a ' +ans)%26;} inline void Add (int x,int y) {v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} struct Trie{int tot,son[s][26],st[s],en[s],dfn;inline int ins0 () {int x=0; for (int i=1;i<=k;i++) {if (!son[x][s[i]]) Son[x][s[i]]=++tot; X=son[x][s[i]]; } return x;} inline int ins1 () {int x=0; for (int i=k;i;i--) {if (!son[x][s[i]]) Son[x][s[i]]=++tot; X=son[x][s[i]]; } return x;} void Dfs (int x) {ST[X]=++DFN; for (int i=0;i<26;i++) if (Son[x][i]) DFS (son[x][i]); EN[X]=DFN;} inline void Ask0 () {int x=0; for (int i=1;i<=k;i++) {if (!son[x][s[i]]) {La=ra=0;return;} X=son[x][s[i]]; } La=st[x],ra=en[x];} inline void Ask1 () {int x=0; for (int i=k;i;i--) {if (!son[x][s[i]]) {Lb=rb=0;return;} X=son[x][s[i]]; } Lb=st[x],rb=en[x];}} A,b;int l[m],r[m],val[m],tot,t[s];int ins (int x,int a,int b,int c) {int y=++tot;val[y]=val[x]+1; if (a==b) return y; int mid= (A+B) >>1; if (c<=mid) l[y]=ins (l[x],a,mid,c), R[y]=r[x];else l[y]=l[x],r[y]=ins (r[x],mid+1,b,c); return y;} int ask (int x,int A,int b) {if (!x) return 0; if (LB<=A&&B<=RB) return val[x]; int mid= (A+B) >>1,t=0; if (lb<=mid) t=ask (L[x],a,mid); if (rb>mid) t+=ask (r[x],mid+1,b); return t;} int main () {scanf ("%d", &n); for (i=1;i<=n;i++) {read (); POSA[I]=A.INS0 (); Posb[i]=b.ins1 (); } a.dfs (0), B.dfs (0); for (i=1;i<=n;i++) Add (A.st[posa[i]],b.st[posb[i]]); for (i=1;i<=a.dfn;i++) for (T[i]=t[i-1],j=g[i];j;j=nxt[j]) t[i]=ins (T[i],1,b.dfn,v[j]); scanf ("%d", &m); while (m--) {read (), A.ask0 (); Read (), B.ask1 (); if (la&&lb) ans=ask (T[RA],1,B.DFN)-ask (T[LA-1],1,B.DFN); else ans=0; printf ("%d\n", ans); } return 0;}
bzoj3483:sgu505 Prefixes and suffixes (inquiry online)