time limit per test : 3 seconds
memory limit per test : 256 megabytes
分数:2500
You are given a string t and n strings s 1 , s 2 , … , s n s_1,s_2,…,s_n s1,s2,…,sn. All strings consist of lowercase Latin letters.
Let f ( t , s ) f(t,s) f(t,s) be the number of occurences of string s s s in string t t t. For example, f ( ′ a a a b a c a a ′ , ′ a a ′ ) = 3 f(′aaabacaa′,′aa′)=3 f(′aaabacaa′,′aa′)=3, and f ( ′ a b a b a ′ , ′ a b a ′ ) = 2 f(′ababa′,′aba′)=2 f(′ababa′,′aba′)=2.
Calculate the value of
∑
i
=
1
n
∑
j
=
1
n
f
(
t
,
s
i
+
s
j
)
∑_{i=1}^n∑_{j=1}^nf(t,s_i+s_j)
i=1∑nj=1∑nf(t,si+sj), where s+t is the concatenation of strings s and t. Note that if there are two pairs
i
1
i_1
i1,
j
1
j_1
j1 and
i
2
i_2
i2,
j
2
j_2
j2 such that
s
i
1
+
s
j
1
=
s
i
2
+
s
j
2
s_{i1}+s_{j1}=s_{i2}+s_{j2}
si1+sj1=si2+sj2, you should include both
f
(
t
,
s
i
1
+
s
j
1
)
f(t,s_{i1}+s_{j1})
f(t,si1+sj1) and
f
(
t
,
s
i
2
+
s
j
2
)
f(t,s_{i2}+s_{j2})
f(t,si2+sj2) in answer.
Input
The first line contains string
t
(
1
≤
∣
t
∣
≤
2
⋅
1
0
5
)
t(1≤|t|≤2⋅10^5)
t(1≤∣t∣≤2⋅105).
The second line contains integer
n
(
1
≤
n
≤
2
⋅
1
0
5
)
n(1≤n≤2⋅10^5)
n(1≤n≤2⋅105).
Each of next
n
n
n lines contains string
s
i
(
1
≤
∣
s
i
∣
≤
2
⋅
1
0
5
)
s_i (1≤|s_i|≤2⋅10^5)
si(1≤∣si∣≤2⋅105).It is guaranteed that
∑
i
=
1
n
∣
s
i
∣
≤
2
⋅
1
0
5
∑_{i=1}^n|s_i|≤2⋅10^5
i=1∑n∣si∣≤2⋅105. All strings consist of lowercase English letters.
Output
Print one integer — the value of ∑ i = 1 n ∑ j = 1 n f ( t , s i + s j ) ∑_{i=1}^n∑_{j=1}^n f(t,s_i+s_j) i=1∑nj=1∑nf(t,si+sj).
Examples
Input
aaabacaa
2
a
aa
Output
5
Input
aaabacaa
4
a
a
a
b
Output
33
题意:
给定一个字符串
t
t
t和
n
n
n个小字符串
{
s
i
}
\{s_i\}
{si}
询问
∑
i
=
1
n
∑
j
=
1
n
f
(
t
,
s
i
+
s
j
)
∑_{i=1}^n∑_{j=1}^n f(t,s_i+s_j)
i=1∑nj=1∑nf(t,si+sj)
f
(
t
,
s
)
f(t,s)
f(t,s)是
s
s
s在
t
t
t中出现的次数。
如果出现不一样的
(
i
,
j
)
(i,j)
(i,j)对相加之后的字符串相同,请重复计算。
题解:
AC自动机上dp
首先用正反两种
{
s
i
}
\{s_i\}
{si}串构建2个自动机
g
[
i
]
g[i]
g[i]表示结束位置为
i
i
i的串的种类数。
f
[
i
]
f[i]
f[i]表示结尾为自动机的节点
i
i
i的串的数量。
答案就是
∑
i
=
1
l
e
n
(
t
)
−
1
t
r
[
0
]
.
f
[
i
]
∗
t
r
[
1
]
.
f
[
l
e
n
(
t
)
−
i
]
\sum_{i=1}^{len(t)-1} tr[0].f[i]*tr[1].f[len(t)-i]
∑i=1len(t)−1tr[0].f[i]∗tr[1].f[len(t)−i]
#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;
}