time limit per test : 3 seconds
memory limit per test : 256 megabytes
分数:2500
You are given a string t and n strings . All strings consist of lowercase Latin letters.
Let be the number of occurences of string in string . For example, , and .
Calculate the value of
, where s+t is the concatenation of strings s and t. Note that if there are two pairs
,
and
,
such that
, you should include both
and
in answer.
Input
The first line contains string
.
The second line contains integer
.
Each of next
lines contains string
.It is guaranteed that
. All strings consist of lowercase English letters.
Output
Print one integer — the value of .
Examples
Input
aaabacaa
2
a
aa
Output
5
Input
aaabacaa
4
a
a
a
b
Output
33
题意:
给定一个字符串
和
个小字符串
询问
是
在
中出现的次数。
如果出现不一样的
对相加之后的字符串相同,请重复计算。
题解:
AC自动机上dp
首先用正反两种
串构建2个自动机
表示结束位置为
的串的种类数。
表示结尾为自动机的节点
的串的数量。
答案就是
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int D=27;
const int MAXN=200004;
struct AC{
int cnt;
queue<int>q;
ll f[MAXN],g[MAXN];
int ch[MAXN][D],fa[MAXN];
AC(){
while(!q.empty())q.pop();
for(int i=0;i<=cnt;i++){
f[i]=0;g[i]=0;
memset(ch[i],0,sizeof(ch[i]));
fa[i]=0;
}
cnt=0;
}
bool add(char *s,int l){
int u=0;
for(int i=1;i<=l;i++){
int to=s[i]-'a';
if(!ch[u][to]){
ch[u][to]=++cnt;
}
u=ch[u][to];
}
f[u]++;
return 1;
}
void build(){
for(int i=0;i<D;i++){
if(ch[0][i]){
q.push(ch[0][i]);
f[ch[0][i]]+=f[0];
}
}
while(!q.empty()){
int x=q.front();q.pop();
for(int i=0;i<D;i++){
if(ch[x][i]){
fa[ch[x][i]]=ch[fa[x]][i];
f[ch[x][i]]+=f[fa[ch[x][i]]];
q.push(ch[x][i]);
}
else{
ch[x][i]=ch[fa[x]][i];
}
}
}
}
void solve(char *s,int l){
int u=0;
for(int i=1;i<=l;i++){
u=ch[u][s[i]-'a'];
g[i]=f[u];
}
}
}tr[2];
ll ans;
int n;
char t[MAXN],s[MAXN];
int main(){
scanf("%s",t+1);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
int l=strlen(s+1);
tr[0].add(s,l);
reverse(s+1,s+l+1);
tr[1].add(s,l);
}
int lt=strlen(t+1);
for(int i=0;i<2;i++){
tr[i].build();
tr[i].solve(t,lt);
reverse(t+1,t+lt+1);
}
ans=0;
for(int i=1;i<lt;i++){
ans+=tr[0].g[i]*tr[1].g[lt-i];
}
printf("%lld\n",ans);
return 0;
}