zoukankan      html  css  js  c++  java
  • E. You Are Given Some Strings...

    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<<'
    ';
        for(int i=1;i<=len;i++){
            ans+=(long long)ac1.sum[i-1]*ac2.sum[len-i-1];
        }
        cout<<ans<<'
    ';
    }
  • 相关阅读:
    VMware80端口映射
    固态硬盘安装win7系统问题。
    正向代理服务器,反向代理服务器
    Oray.com花生壳路由器配置注意
    Nginx命令
    Nginx反向代理图片总结
    C#获取视频文件播放长度
    汉语拼音的发展
    MVC 公共类App_Code不识别
    记录一下学习Android的小知识
  • 原文地址:https://www.cnblogs.com/liulex/p/11330105.html
Copyright © 2011-2022 走看看