#include <bits/stdc++.h> #define FRER() freopen("i.txt","r",stdin); using namespace std; /* ac自动机 我们考虑两个串的连接处,对于文本串,如果在t[i]匹配了x个,那么说明以 t[i]为结尾的串有x,反着找val[t[i]],说明以t[i]为结尾的串有x,记录乘积 来反应最终有多少贡献值 傻逼了,把int ch,弄成char ch了,我是憨憨 */ typedef long long ll; const int maxn=2e5+100,M=27; struct ACH { int ch[maxn][M]; int f[maxn]; int sz=1; int C[maxn]; int val[maxn]; void init() { memset(C,0,sizeof C); memset(f,0,sizeof f); memset(val,0,sizeof val); } int index(char c) { return c-'a'; } void inser(char *s) { int len=strlen(s); int u=0; for(int i=0; i<len; i++) { int c=index(s[i]); if(!ch[u][c]) ch[u][c]=sz++; u=ch[u][c]; } val[u]++; } void getFile() { f[0]=0; queue<int>que; for(int i=0; i<M; i++) { if(ch[0][i]) que.push(ch[0][i]),f[ch[0][i]]=0; } while(!que.empty()) { int r=que.front(); que.pop(); val[r]+=val[f[r]]; for(int i=0; i<M; i++) { int u=ch[r][i]; if(!u) { ch[r][i]=ch[f[r]][i]; continue; } que.push(u); int v=f[r]; f[u]=ch[v][i]; } } } int fin(char *s) { int len=strlen(s); int j=0; for(int i=0; i<len; i++) { j=ch[j][s[i]-'a']; C[i]=val[j]; } } } ach,ach1; int main() { char s[maxn],s1[maxn]; int n; scanf("%s",s); scanf("%d",&n); ach.init(),ach1.init(); for(int i=0; i<n; i++) { scanf("%s",s1); ach.inser(s1); reverse(s1,s1+strlen(s1)); ach1.inser(s1); } ach.getFile(),ach1.getFile(); ach.fin(s); int len=strlen(s); reverse(s,s+strlen(s)); ach1.fin(s); ll ans=0; for(int i=0; i<len-1; i++)//是len-1,不是len { // printf("i=%d ach.C[i]=%d %d %d ",i,ach.C[i],ach1.C[len-i-2],len-i-2); ans+=(ll)ach1.C[i]*(ll)ach.C[len-i-2]; } printf("%lld ",ans); return 0; }