[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 s1,s2,,sns_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 ss in string tt. For example, f(aaabacaa,aa)=3f(′aaabacaa′,′aa′)=3, and f(ababa,aba)=2f(′ababa′,′aba′)=2.

Calculate the value of i=1nj=1nf(t,si+sj)∑_{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 i1i_1, j1j_1 and i2i_2, j2j_2 such that si1+sj1=si2+sj2s_{i1}+s_{j1}=s_{i2}+s_{j2}, you should include both f(t,si1+sj1)f(t,s_{i1}+s_{j1}) and f(t,si2+sj2)f(t,s_{i2}+s_{j2}) in answer.
Input

The first line contains string t(1t2105)t(1≤|t|≤2⋅10^5).
The second line contains integer n(1n2105)n(1≤n≤2⋅10^5).
Each of next nn lines contains string si(1si2105)s_i (1≤|s_i|≤2⋅10^5).It is guaranteed that i=1nsi2105∑_{i=1}^n|s_i|≤2⋅10^5. All strings consist of lowercase English letters.

Output

Print one integer — the value of i=1nj=1nf(t,si+sj)∑_{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

題意:
給定一個字符串ttnn個小字符串{si}\{s_i\}
詢問i=1nj=1nf(t,si+sj)∑_{i=1}^n∑_{j=1}^n f(t,s_i+s_j)
f(t,s)f(t,s)sstt中出現的次數。
如果出現不一樣的(i,j)(i,j)對相加之後的字符串相同,請重複計算。

題解:
AC自動機上dp
首先用正反兩種{si}\{s_i\}串構建2個自動機
g[i]g[i]表示結束位置爲ii的串的種類數。
f[i]f[i]表示結尾爲自動機的節點ii的串的數量。
答案就是i=1len(t)1tr[0].f[i]tr[1].f[len(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章