zoukankan      html  css  js  c++  java
  • BZOJ3172 [Tjoi2013]单词 【AC自动机】

    3172: [Tjoi2013]单词

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 4293  Solved: 2083
    [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



    复习了一下AC自动机


    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    using namespace std;
    const int maxn = 305,maxm = 1310005,INF = 1000000000;
    char T[maxm];
    int pos[maxn],ans[maxn],ch[maxm][26],last[maxm],f[maxm],N,siz = 0;;
    vector<int> tag[maxm];
    void insert(int p){
    	int u = 0,id;
    	for (int j = pos[p - 1]; j < pos[p]; j++){
    		id = T[j] - 'a';
    		u = ch[u][id] ? ch[u][id] : ch[u][id] = ++siz;
    	}
    	tag[u].push_back(p);
    }
    void getf(){
    	queue<int> q;
    	for (int i = 0; i < 26; i++) if (ch[0][i]) q.push(ch[0][i]);
    	int u,v;
    	while (!q.empty()){
    		u = q.front();
    		q.pop();
    		for (int i = 0; i < 26; i++){
    			v = ch[u][i];
    			if (!v) ch[u][i] = ch[f[u]][i];
    			else f[v] = ch[f[u]][i],q.push(v),last[v] = tag[f[v]].size() ? f[v]:last[f[v]];
    		}
    	}
    }
    void re(int u){
    	while (u){
    		for (unsigned int j = 0; j < tag[u].size();j++)
    			ans[tag[u][j]]++;
    		u = last[u];
    	}
    }
    void AC(int p){
    	int u = 0,id;
    	for (int i = pos[p - 1]; i < pos[p]; i++){
    		id = T[i] - 'a';
    		u = ch[u][id];
    		if (tag[u].size()) re(u);
    		else if (last[u]) re(last[u]);
    	}
    }
    int main()
    {
    	scanf("%d",&N);
    	for (int i = 1; i <= N; i++){
    		scanf("%s",T + pos[i - 1]);
    		pos[i] = pos[i - 1] + strlen(T + pos[i - 1]);
    		insert(i);
    	}
    	getf();
    	REP(i,N) AC(i);
    	REP(i,N) printf("%d
    ",ans[i]);
    	return 0;
    }
    


  • 相关阅读:
    gulp的使用
    Js中call(),apply()的使用
    HTML中<meta>标签的使用
    字符串及数组常用方法
    css—transform
    《Java设计模式》——适配器模式
    全文检索工具包Lucene以及企业及应用Solr的学习(二)—— solr中edismax用到的Query Function以及java扩展
    全文检索工具包Lucene以及企业及应用Solr的学习(一)
    最近发现服务器发生了一些问题
    TxT读取写入
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282816.html
Copyright © 2011-2022 走看看