歌词(AC自动机)

题目描述

C同学很喜欢唱歌。唱了n首歌后他发现有一些歌词在这n首歌中经常出现。比如:
《两只蝴蝶》
亲爱的你慢慢飞
小心前面带刺的玫瑰
亲爱的你张张嘴
风中花香会让你沉醉
……
《风雨彩虹铿锵玫瑰》
一切美好只是昨日沉醉
淡淡苦涩才是今天滋味
想想明天又是雨晒风吹
再苦再累无惧无畏
身上的痛让我难以入睡
脚下的路还有更多的累
追逐梦想总是百转千回
无怨无悔从容面对
风雨彩虹 铿锵玫瑰
再多忧伤再多痛苦自己去背
风雨彩虹 铿锵玫瑰
……
在上述两首歌的片段中,玫瑰总共出现了3次,风总共出现了4次。
C同学列出了w个他认为经常出现的歌词,他想知道每个歌词在这n首歌中出现了多少次。

ps:歌词可能会有重复的。

输入格式

第一行一个整数w。
接下来w行,每行一个字符串,第i行表示第i个歌词。
接下来一个整数n。
接下来n行,每行一个字符串,第i行表示第i首歌。
字符串由大小写字母,数字与"-"组成。

输出格式 

一共w行,每行一个整数,第i行表示第i个歌词在这n首歌中出现了多少次。

数据范围

输入样例 

【样例一输入】
5
he
she
sher
his
hers
2
ushers
she-said-he-said-she-said-he-said-his
【样例二输入】
3
who
shawty
hawt
2
Get-it-shawty-Get-it-shawty
Whoa-W-W-Whoa-Shawtyyyyy
样例三输入:
1
aa
1
aaa

输出样例 

【样例一输出】
5
3
1
1
1
【样例二输出】
0
2
3
样例三输出:
2

由于本人是蒟蒻,不能自己AC,所以请来了AC自动机神犇帮我自动AC……

题解:一道裸的AC自动机

        我们把所给的歌词构建一个AC自动机,然后每一首歌都去与AC自动机匹配。

        在本题需要注意的是:假如某一个字符能匹配上,那么就一直往回找该字符的fail节点,并判断是否出现以fail(包括当前刚刚匹配的字符)节点为结尾的单词。

附:AC自动机以前也只是看过文章,做的题少,所以写起来漏洞百出,调了好久。

#include<algorithm>
#include<fstream>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;

int w,n,len,cur,pt[1010],ans[550];
char c[50050];
struct tedge
{
    int n,num;
    tedge *nex[65],*f;
}tree[500050];
tedge *Root = tree+0;
tedge *d[500050];

int Change(char q)
{
    if (q>='0'&&q<='9') return q-48;
    if (q>='a'&&q<='z') return q-87;
    if (q>='A'&&q<='Z') return q-29;
    return 62;
}

tedge *NewNode()
{
    cur++;
    return tree+cur;
}

void Insert(tedge *root,int wei,int num)
{
    if (wei>len) 
    {
        if (root->n==0) 
        {
            root->n = 1;
            root->num = num;
        }
        else pt[num] = root->num;
        return;
    }
    if (root->nex[Change(c[wei])]==NULL)
    {
        tedge *y = NewNode();
        root->nex[Change(c[wei])] = y;
        Insert(y,wei+1,num);
    }
    else Insert(root->nex[Change(c[wei])],wei+1,num);
}

void Make_fail()
{
    int h,t;  h = t = 1;  d[1] = tree+0;
    while (h<=t)
    {
        tedge *fro = d[h];
        for (int i=0; i<=62; i++)
        {
            if (fro->nex[i]==NULL) continue;
            t++;  d[t] = fro->nex[i];
            tedge *fail = fro->f;
            while (fail!=NULL)
            {
                if (fail->nex[i]!=NULL)
                {
                    fro->nex[i]->f = fail->nex[i];
                    break;
                }
                fail = fail->f;
            }
            if (fro->nex[i]->f==NULL) fro->nex[i]->f = Root;
        }
        h++;
    }
    return;
}

void Compare()
{
    tedge *p1 = Root;
    int p2 = 0;
    while (p2<=len)
    {
        if (p1->nex[Change(c[p2])]!=NULL) 
        {
            p1 = p1->nex[Change(c[p2])];
            p2++;
            tedge *p3 = p1;
            while (p3!=Root&&p3!=NULL)
            {
                if (p3->n==1) ans[p3->num]++;
                p3 = p3->f;
            }
        }
        else 
        {
            p1 = p1->f;
            if (p1==NULL) p1 = Root;
            if (p1==Root&&p1->nex[Change(c[p2])]==NULL) p2++;
        }
    }
}

int main()
{
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    scanf("%d",&w);
    for (int i=1; i<=w; i++)
    {
        scanf("%s",&c);
        len = strlen(c)-1;
        Insert(Root,0,i);
    }
    tree[0].f = NULL;
    Make_fail();
    scanf("%d",&n);
    for (int i=1; i<=n; i++)
    {
        scanf("%s",&c);
        len = strlen(c)-1;
        Compare();
    }
    for (int i=1; i<=w; i++)
    if (pt[i]!=0) printf("%d\n",ans[pt[i]]);
    else printf("%d\n",ans[i]);
    return 0;
}

 

转载于:https://www.cnblogs.com/Janous/p/7565278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
森林防火应急联动指挥系统是一个集成了北斗定位/GPS、GIS、RS遥感、无线网络通讯、4G网络等技术的现代化智能系统,旨在提高森林火灾的预防和扑救效率。该系统通过实时监控、地图服务、历史数据管理、调度语音等功能,实现了现场指挥调度、语音呼叫通讯、远程监控、现场直播、救火人员生命检测等工作的网络化、智能化、可视化。它能够在火灾发生后迅速组网,确保现场与指挥中心的通信畅通,同时,系统支持快速部署,适应各种极端环境,保障信息的实时传输和历史数据的安全存储。 系统的设计遵循先进性、实用性、标准性、开放性、安全性、可靠性和扩展性原则,确保了技术的领先地位和未来的发展空间。系统架构包括应急终端、无线专网、应用联动应用和服务组件,以及安全审计模块,以确保用户合法性和数据安全性。部署方案灵活,能够根据现场需求快速搭建应急指挥平台,支持高并发视频直播和大容量数据存储。 智能终端设备具备三防等级,能够在恶劣环境下稳定工作,支持北斗+GPS双模定位,提供精确的位置信息。设备搭载的操作系统和处理器能够处理复杂的任务,如高清视频拍摄和数据传输。此外,设备还配备了多种传感器和接口,以适应不同的使用场景。 自适应无线网络是系统的关键组成部分,它基于认知无线电技术,能够根据环境变化动态调整通讯参数,优化通讯效果。网络支持点对点和点对多点的组网模式,具有低功耗、长距离覆盖、强抗干扰能力等特点,易于部署和维护。 系统的售后服务保障包括安装实施服务、系统维护服务、系统完善服务、培训服务等,确保用户能够高效使用系统。提供7*24小时的实时故障响应,以及定期的系统优化和维护,确保系统的稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值