码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ2754】喵星球上的点名(AC自动机)

时间:2018-02-25 11:17:49      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:com   匹配   pop   line   algorithm   zoj   ace   span   size   

【BZOJ2754】喵星球上的点名(AC自动机)

题面

BZOJ

题解

友情提示:此题请不要在cogs上提交,它的数据有毒

对于点名串构建\(AC\)自动机
然后把名字丢进去进行匹配,
大力统计一下答案即可
当然,要用\(map\)记录\(trie\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 52000
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
void ReadStr(vector<int> &a)
{
    int x=read();
    a.resize(x+1);
    a[0]=x;
    for(int i=1;i<=x;++i)a[i]=read();
}
vector<int> nam[MAX],fam[MAX];
vector<int> sub[MAX];
map<int,int>::iterator it;
int n,m;
struct Node
{
    map<int,int> son;
    int ff,fl;
    set<int> lst;
}t[MAX<<2];
int tot,vis[MAX],ans1[MAX],ans2[MAX];
void insert(vector<int> a,int g)
{
    int now=0;
    for(int i=1;i<=a[0];++i)
    {
        if(!t[now].son[a[i]])
            t[now].son[a[i]]=++tot;
        now=t[now].son[a[i]];
    }
    t[now].lst.insert(g);
    t[now].fl=1;
}
void BuildFail()
{
    queue<int> Q;
    for(it=t[0].son.begin();it!=t[0].son.end();++it)Q.push(it->second);
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        if(!t[u].son.size())continue;
        for(it=t[u].son.begin();it!=t[u].son.end();++it)
        {
            int v=it->second,c=it->first,p=t[u].ff;
            while(p&&!t[p].son[c])p=t[p].ff;
            if(t[p].son[c])t[v].ff=t[p].son[c];
            Q.push(v);
            t[v].fl|=t[t[v].ff].fl;
        }
    }
}
void Work(vector<int> a,int str)
{
    int now=0;
    for(int i=1;i<=a[0];++i)
    {
        int c=a[i];
        if(t[now].son[c])now=t[now].son[c];
        else
        {
            while(now&&!t[now].son[c])now=t[now].ff;
            if(t[now].son[c])now=t[now].son[c];
        }
        if(t[now].fl)
        {
            int p=now;
            while(p)
            {
                
                for(set<int>::iterator it=t[p].lst.begin();it!=t[p].lst.end();++it)
                    if(vis[*it]!=str){ans1[*it]++;ans2[str]++;vis[*it]=str;}
                p=t[p].ff;
            }
        }
    }
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;++i)
    {
        ReadStr(nam[i]);
        ReadStr(fam[i]);
    }
    for(int i=1;i<=m;++i)ReadStr(sub[i]);
    for(int i=1;i<=m;++i)insert(sub[i],i);
    BuildFail();
    for(int str=1;str<=n;++str)
    {
        Work(nam[str],str);
        Work(fam[str],str);
    }
    for(int i=1;i<=m;++i)printf("%d\n",ans1[i]);
    for(int i=1;i<=n;++i){printf("%d",ans2[i]);(i==n)?putchar('\n'):putchar(' ');}
    return 0;
}

【BZOJ2754】喵星球上的点名(AC自动机)

标签:com   匹配   pop   line   algorithm   zoj   ace   span   size   

原文地址:https://www.cnblogs.com/cjyyb/p/8468616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!