zoukankan      html  css  js  c++  java
  • BZOJ 3172: [Tjoi2013]单词

    3172: [Tjoi2013]单词

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 3439  Solved: 1650
    [Submit][Status][Discuss]

    Description

    某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

    Input

    第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

    Output

    输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。

    Sample Input

    3
    a
    aa
    aaa

    Sample Output

    6
    3
    1

    HINT

     

    Source

    分析:

    我们对于每一个节点维护其子树fail指针和...就是答案...

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    //by NeighThorn
    using namespace std;
    
    const int maxn=200+5,maxm=1000000+5;
    
    int n,tot,head,tail,q[maxm],pos[maxn];
    
    char s[maxm];
    
    struct trie{
        int sum,fail,nxt[26];  
    }tr[maxm];
    
    inline void insert(int &x){
        scanf("%s",s);int p=0,len=strlen(s);
        for(int i=0;i<len;i++){
            if(!tr[p].nxt[s[i]-'a'])
                tr[p].nxt[s[i]-'a']=++tot,tr[tot].fail=-1;
            p=tr[p].nxt[s[i]-'a'],tr[p].sum++;
        }
        x=p;
    }
    
    inline void buildACM(void){
        head=0,tail=0;q[0]=0;
        while(head<=tail){
            int id=q[head++],p=-1;
            for(int i=0;i<26;i++)
                if(tr[id].nxt[i]){
                    if(id){
                        p=tr[id].fail;
                        while(p!=-1){
                            if(tr[p].nxt[i]){
                                tr[tr[id].nxt[i]].fail=tr[p].nxt[i];
                                break;
                            }
                            p=tr[p].fail;
                        }
                        if(p==-1) tr[tr[id].nxt[i]].fail=0;
                    }
                    else
                        tr[tr[id].nxt[i]].fail=0;
                    q[++tail]=tr[id].nxt[i];
                }
        }
        for(int i=tail;i>=0;i--)
            tr[tr[q[i]].fail].sum+=tr[q[i]].sum;
    }
    
    signed main(void){
        scanf("%d",&n);tr[0].fail=-1;
        for(int i=1;i<=n;i++)
            insert(pos[i]);
        buildACM();
        for(int i=1;i<=n;i++)
            printf("%d
    ",tr[pos[i]].sum);
        return 0;
    }
    

      


    By NeighThorn

  • 相关阅读:
    全国城市经纬度
    CentOS下SSH无密码登录的配置
    Nginx 1.9+PHP5.6 环境搭建
    Sphinx 2.2.11-release reference manual
    JVM 内存管理机制
    solr 3.5.0 与 tomcat 7.0.5 整合配置
    lucene 分词实现
    lucene 索引 demo
    lucene 搜索demo
    Lucene 简单API使用
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6402223.html
Copyright © 2011-2022 走看看