zoukankan      html  css  js  c++  java
  • bzoj3172 [Tjoi2013]单词

    [Tjoi2013]单词

    Time Limit: 10 Sec Memory Limit: 512 MB

    Description

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

    Input

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

    Output

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

    Sample Input

    3

    a

    aa

    aaa

    Sample Output

    6

    3

    1

    <br >
    <br >
    <br >
    <br >
    <br >
    <br >
    <br >

    由KMP转向AC自动机。。。。感觉还可以,自动脑补.jpg
    大概就是你一个串走了次他的fail能连接的地方显然也可以走,你倒着搞一波就差不多了。。。

    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6 + 5;
    struct lpl{
    	int sum, fail, ch[30];
    }node[maxn];
    int n, len, cnt, tot, pos[205], Q[maxn];
    char s[maxn];
    
    inline void putit()
    {
    	scanf("%d", &n);	int now, lin; cnt = 1;
    	for(int i = 1; i <= n; ++i){
    		scanf("%s", s + 1); len = strlen(s + 1); now = 1;
    		for(int j = 1; j <= len; ++j){
    			lin = s[j] - 'a' + 1;
    			if(!node[now].ch[lin]){node[now].ch[lin] = ++cnt;}
    			now = node[now].ch[lin]; node[now].sum++;
    			if(j == len) pos[i] = now;
    		}		
    	}
    }
    
    inline void workk()
    {
    	queue<int> q;
    	q.push(1); int now, t;
    	while(!q.empty()){
    		now = q.front(); q.pop();
    		Q[++tot] = now;
    		for(int i = 1; i <= 26; ++i){
    			if(!node[now].ch[i]) continue;
    			q.push(node[now].ch[i]);
    			if(now == 1){
    				node[node[now].ch[i]].fail = 1;
    				continue;
    			}
    			t = node[now].fail;
    			while(!node[t].ch[i] && t) t = node[t].fail;
    			if(!t) node[node[now].ch[i]].fail = 1;
    			else node[node[now].ch[i]].fail = node[t].ch[i];
    		}
    	}
    }
    
    inline void print()
    {
    	for(int i = tot; i >= 1; --i)	node[node[Q[i]].fail].sum += node[Q[i]].sum;
    	for(int i = 1; i <= n; ++i) printf("%d
    ", node[pos[i]].sum);
    }
    
    int main()
    {
    	putit();
    	workk();
    	print();
    	return 0;
    }
    
    
    心如花木,向阳而生。
  • 相关阅读:
    小米面试之股票收益最大
    第三周:同时管理64位和32位版本的Python,并用Pyinstaller打包成exe
    第三周 anaconda的安装
    第二周:python实现线性回归(哑变量回归)的高效方法
    第一周:在python里调用C文件中函数
    13G:神奇的数列
    13F:图像分割
    13E:吃奶酪
    13D:拖延症
    13B:回文子串
  • 原文地址:https://www.cnblogs.com/LLppdd/p/9057960.html
Copyright © 2011-2022 走看看