[codeforces1202E]You Are Given Some Strings...

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 . All strings consist of lowercase Latin letters.

Let f ( t , s ) f(t,s) be the number of occurences of string s s in string t t . For example, f ( a a a b a c a a , a a ) = 3 f(′aaabacaa′,′aa′)=3 , and f ( a b a b a , a b a ) = 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) , where s+t is the concatenation of strings s and t. Note that if there are two pairs i 1 i_1 , j 1 j_1 and i 2 i_2 , j 2 j_2 such that s i 1 + s j 1 = s i 2 + s j 2 s_{i1}+s_{j1}=s_{i2}+s_{j2} , you should include both f ( t , s i 1 + s j 1 ) f(t,s_{i1}+s_{j1}) and f ( t , s i 2 + s j 2 ) f(t,s_{i2}+s_{j2}) in answer.
Input

The first line contains string t ( 1 t 2 1 0 5 ) t(1≤|t|≤2⋅10^5) .
The second line contains integer n ( 1 n 2 1 0 5 ) n(1≤n≤2⋅10^5) .
Each of next n n lines contains string s i ( 1 s i 2 1 0 5 ) s_i (1≤|s_i|≤2⋅10^5) .It is guaranteed that i = 1 n s i 2 1 0 5 ∑_{i=1}^n|s_i|≤2⋅10^5 . 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) .

Examples
Input

aaabacaa
2
a
aa

Output

5

Input

aaabacaa
4
a
a
a
b

Output

33

题意:
给定一个字符串 t t n n 个小字符串 { s i } \{s_i\}
询问 i = 1 n j = 1 n f ( t , s i + s j ) ∑_{i=1}^n∑_{j=1}^n f(t,s_i+s_j)
f ( t , s ) f(t,s) s s t t 中出现的次数。
如果出现不一样的 ( i , j ) (i,j) 对相加之后的字符串相同,请重复计算。

题解:
AC自动机上dp
首先用正反两种 { s i } \{s_i\} 串构建2个自动机
g [ i ] g[i] 表示结束位置为 i i 的串的种类数。
f [ i ] f[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]

#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;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/100805190