zoukankan      html  css  js  c++  java
  • P3966 [TJOI2013]单词

    传送门

    AC自动机

    一看就知道是AC自动机

    它问的是每一个单词在所有单词中出现的次数

    对所有单词搞一个AC自动机

    然后把所有单词连在一起,中间用一个不会出现的字符或者其他什么的隔开

    然后把连在一起的串放到AC自动机上搞匹配就行了

    要注意单词可能有重复

    所以要把重复的单词判一下

    具体看代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=1e6+7;
    int n,mp[207];
    char s[N];
    int c[N][27],pd[N],fail[N],g[N],cnt;
    char a[N]; int b[N+207],len;
    inline void ins(int num)//插入单词
    {
        int u=0,l=strlen(a);
        for(int i=0;i<l;i++)
        {
            int v=a[i]-'a'+1;
            b[++len]=v;//把匹配串处理一下
            if(!c[u][v]) c[u][v]=++cnt;
            u=c[u][v];
        }
        if(!pd[u]) pd[u]=num;
        mp[num]=pd[u];//用来处理重复的单词,mp[i]表示第i个单词最早出现时的位置
        b[++len]=-1;//单词之间用-1隔开
    }
    queue <int> q;
    inline void pre()//预处理fail和g,g[x]表示从x一直走失配边,走到的第一个结束标记的位置
    {
        for(int i=1;i<=26;i++)
            if(c[0][i]) q.push(c[0][i]);
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            for(int i=1;i<=26;i++)
            {
                int v=c[u][i];
                if(!v) c[u][i]=c[fail[u]][i];
                else
                {
                    fail[v]=c[fail[u]][i];
                    g[v]= pd[fail[v]] ? fail[v] : g[fail[v]];
                    q.push(v);
                }
            }
        }
    }
    int ans[207];
    inline void query()//匹配
    {
        int u=0;
        for(int i=1;i<=len;i++)
        {
            if(b[i]==-1)//如果走到分隔标记,就回到起点匹配
            {
                u=0;
                continue;
            }
            u=c[u][b[i]];
            if(pd[u]) ans[pd[u]]++;
            for(int j=g[u];j;j=g[j])
                ans[pd[j]]++;
        }
        for(int i=1;i<=n;i++)
            printf("%d
    ",ans[mp[i]]);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a);
            ins(i);
        }
        pre();
        query();
        return 0;
    }
  • 相关阅读:
    day02 基本数据类型与运算符
    java的基本数据类型--四类八种
    mysql 语句
    5 函数
    4 流程控制
    2 字符串操作 日期
    在Win7虚拟机下搭建Hadoop2.6.0+Spark1.4.0单机环境
    如何排查java.lang.NoSuchMethodError错误
    搭建Hadoop2.6.0+Eclipse开发调试环境
    在Win7虚拟机下搭建Hadoop2.6.0伪分布式环境
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9672882.html
Copyright © 2011-2022 走看看