E. You Are Given Some Strings...

Stella981
• 阅读 617

E. You Are Given Some Strings...

AC自动机

求一个串$t$中包含子串$s_{i}+s_{j}$的个数。

可以正反跑两遍AC自动机

正着跑,表示$s_{i}$结束,反正跑对应$s_{i}$开头

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define maxm 28
struct AC{
int trieN;
int ch[maxn][maxm];
int val[maxn],tt[maxn];
int fail[maxn];
int sum[maxn];
vector<int> v;
void init()
{
    trieN=-1;
    newnod();
}
int newnod()
{
    memset(ch[++trieN],0,sizeof ch[0]);
    val[trieN]=fail[trieN]=0;
    return trieN;
}
void insert(const string & str)
{
    int cur=0;
    for(int i=0;i<str.size();i++){
        int d=str[i]-'a';
        if(!ch[cur][d]){
            ch[cur][d]=newnod();
        }
        cur=ch[cur][d];
    }
    val[cur]++;
}
void build()
{
    queue<int> q;
    for(int i=0;i<maxm;i++){
        if(ch[0][i]){
            q.push(ch[0][i]);
        }
    }
    while(!q.empty()){
        int cur=q.front();
        v.push_back(cur);
        q.pop();
        for(int i=0;i<maxm;i++){
            if(ch[cur][i]){
                fail[ch[cur][i]]=ch[fail[cur]][i];
                q.push(ch[cur][i]);
            }else{
                ch[cur][i]=ch[fail[cur]][i];
            }
        }
    }
    for(int i=0;i<v.size();i++){
        int u=v[i];
        tt[u]=tt[fail[u]]+val[u];
    }///优化??
}

void  query(const string & str)
{

    int res=0,cur=0;
    for(int i=0;str[i];i++){
        int d=str[i]-'a';
        cur=ch[cur][d];

        sum[i]=tt[cur];
        res=0;
    }
    //return res;
}
}ac1,ac2;

int main()
{
    string s,t;
    cin>>t;
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        cin>>s;

        ac1.insert(s);
        reverse(s.begin(),s.end());
        ac2.insert(s);
    }
    ac1.build();
    ac2.build();
    ac1.query(t);
    long long ans=0;
    reverse(t.begin(),t.end());
    ac2.query(t);
    int len=t.length();
    /*for(int i=0;i<len;i++){
        cout<<ac1.sum[i]<<" "<<ac2.sum[i]<<endl;
    }*/
   // cout<<len<<'\n';
    for(int i=1;i<=len;i++){
        ans+=(long long)ac1.sum[i-1]*ac2.sum[len-i-1];
    }
    cout<<ans<<'\n';
}
点赞
收藏
评论区
推荐文章
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
C++ 中字符串查找、字符串截取、字符串替换
参照:C基础string截取、替换、查找子串函数(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fcatgatp%2Fp%2F6407788.html)1、字符串查找s.find(s1)//查找
Wesley13 Wesley13
3年前
P2P技术揭秘.P2P网络技术原理与典型系统开发
Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E
Stella981 Stella981
3年前
Codeforces Round #479 (Div. 3) F. Consecutive Subsequence
标签:DP题目链接(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F977%2Fproblem%2FF)
Stella981 Stella981
3年前
Codeforces Round #616 (Div. 2)
A.EvenButNotEven(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F1291%2Fproblem%2FA)题意:给你一个很长的数,可以删减里面的任意数字,要求本身不能除以2,但是该数的各位和能除以2,输出任意符合
Stella981 Stella981
3年前
Codeforces Round #565 (Div. 3) C. Lose it!
链接:https://codeforces.com/contest/1176/problem/C(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fcodeforces.com%2Fcontest%2F1176%2Fproblem%2FC)题意:Youare
Stella981 Stella981
3年前
CF 833 B. The Bakery
B.TheBakeryhttp://codeforces.com/contest/833/problem/B(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F833%2Fproblem%2FB)题
Stella981 Stella981
3年前
LOJ6500. 「雅礼集训 2018 Day2」操作(哈希+差分)
题目链接https://loj.ac/problem/6500(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Floj.ac%2Fproblem%2F6500)题解区间取反$01$串的经典套路是差分。我们令$b\_ia\_i\\{\\rmxor
Stella981 Stella981
3年前
85D Sum of Medians
传送门(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F85%2Fproblem%2FD)题目Inonewellknownalgorithmoffindingthe_k_\thorderst
Wesley13 Wesley13
3年前
HDU 6345(子串查询 暴力)
题意是每组给定一个字符串,在有限查询次数内输出所要查询区间的字典序最小的子串个数。字典序最小的子串,就是所查询区间中字典序最小的单个字符,问题就转化成了求一段区间内字典序最小的字符个数。开始时盲目暴力,直接用桶排序的做法一段一段去求,果然t了(这种就不贴代码了)......然后想到先扫一遍,求出从字符串首位到第i位的最小字符数,再用一个数组存