zoukankan      html  css  js  c++  java
  • hdu 2222 AC自动机学校

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    using namespace std;
    const int maxn=(int)1e6+10;
    const int maxm=(int)5e5+10;
    struct trie{
    int nxt[maxm][26],fail[maxm],ed[maxm];
    int rt,l;
    int newnod(){
    for(int i=0;i<26;i++)nxt[l][i]=-1;
    ed[l++]=0;
    return l-1;
    }
    void init(){
    l=0;rt=newnod();
    }
    void inset(char s[]){
    int now=rt;
    for(int i=0;s[i];i++){
    if(nxt[now][s[i]-'a']==-1)nxt[now][s[i]-'a']=newnod();
    now=nxt[now][s[i]-'a'];
    }
    ed[now]++;
    }
    void build(){
    static queue<int>q;fail[rt]=rt;

    for(int i=0;i<26;i++)
    if(nxt[rt][i]==-1)nxt[rt][i]=rt;
    else{
    fail[nxt[rt][i]]=rt;q.push(nxt[rt][i]);
    }
    while(!q.empty()){
    int now=q.front();
    q.pop();
    for(int i=0;i<26;i++){
    if(nxt[now][i]==-1) nxt[now][i]=nxt[fail[now]][i];
    //如果当前单词的下一个字母结点为空,当前单词的该字母结点指
    //向fail结点的对应字母结点
    else{
    //如果当前单词的下一个字母结点不为空,当前单词的该字母结点的fail结点
    //指向fail结点的对应字母结点
    fail[nxt[now][i]]=nxt[fail[now]][i];
    q.push(nxt[now][i]);
    }
    }
    }
    }
    //fail[i]即i结点所在单词以i结点为结尾和其它单词中以i结点代表字母为结尾的公共最长后前缀的结点
    int query(char s[]){
    int now=rt,res=0;
    for(int i=0;s[i];i++){
    now=nxt[now][s[i]-'a'];
    //新start=上一个start的s[i]字母结点的nxt指向结点,单词存在就指向单词下一个字母,
    //不存在指向别的单词的该字母,就指向fail[st]的nxt指向结点
    //
    int tmp=now;
    printf("s[%d]: %c tmp :%d now:%d ",i,s[i],tmp,now);
    while(tmp!=rt){

    if(ed[tmp]==1)printf("--%d ",tmp);
    res+=ed[tmp];ed[tmp]=0;tmp=fail[tmp];
    printf("tmp:%d ",tmp);
    }
    }
    return res;
    }
    void debug(){
    printf("id = %3d fail = %3d ed= %3d chi = [",0,0,0);
    for(int j=0;j<26;j++)printf("%2c",'a'+j);printf(" ");
    for(int i=0;i<l;i++){
    printf("id = %3d fail = %3d ed= %3d chi = [",i,fail[i],ed[i]);
    for(int j=0;j<26;j++)printf("%2d",nxt[i][j]);printf(" ");
    }
    }

    };
    char s[maxn];
    trie ac;

    void dfs(int st,string tmp=""){
    if(ac.ed[st]!=0) cout<<tmp<<endl;
    for(int i=0;i<26;i++){
    if(ac.nxt[st][i]!=-1) dfs(ac.nxt[st][i],tmp+(char)('a'+i));
    }
    }
    void dfs1(int st,string tmp=""){
    if(ac.ed[st]!=0) cout<<tmp<<endl;
    for(int i=0;i<26;i++){
    if(ac.nxt[st][i]!=0) dfs(ac.nxt[st][i],tmp+(char)('a'+i));
    }
    }
    int main()
    {
    #ifdef shuaishuai
    freopen("C:\Users\hasee\Desktop\a.txt","r",stdin);
    //freopen("C:\Users\hasee\Desktop\b.txt","w",stdout);
    #endif
    int T,n;
    scanf("%d",&T);
    while(T--){
    scanf("%d",&n);
    ac.init();
    for(int i=0;i<n;i++){
    scanf("%s",s);
    ac.inset(s);
    }

    // dfs(0);
    ac.debug();
    ac.build();
    // dfs1(0);
    // for(int i=0;i<ac.l;i++)
    // { printf("%d ",ac.ed[i]);
    // for(int j=0;j<26;j++)printf("%d ",ac.nxt[i][j]);
    // printf(" ");
    // }
    ac.debug();
    scanf("%s",s);
    printf("%d ",ac.query(s));
    }
    return 0;
    }

  • 相关阅读:
    在阿里写了8年代码后,我才明白这些道理
    2017双11交易系统TMF2.0技术揭秘,实现全链路管理
    加入新公司快速进入状态的心得
    Kibana+ElasticSearch实现索引数据的几种查询方式
    记一次jenkins发生的无法判断字符串前后空格
    ansible-playbook调试
    记一次ansible-playbook jenkins传空格的标量导致删除了服务的主目录
    rabbitmq集群中队列的完整性
    html5分割上传实现超大文件无插件网页上传思路
    html5分割上传实现超大文件无插件网页上传功能
  • 原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7526649.html
Copyright © 2011-2022 走看看